我現在已經睜大眼睛瞎了,所以請幫助。從異步方法返回相同的值
當我在一個循環內調用兩次這個方法時,它會返回相同的值。爲什麼?
public async Task<int> RollDice() {
var rnd = new Random();
var selected = 0;
await Task.Run(() => {
selected = rnd.Next(1, 6);
});
return selected;
}
我現在已經睜大眼睛瞎了,所以請幫助。從異步方法返回相同的值
當我在一個循環內調用兩次這個方法時,它會返回相同的值。爲什麼?
public async Task<int> RollDice() {
var rnd = new Random();
var selected = 0;
await Task.Run(() => {
selected = rnd.Next(1, 6);
});
return selected;
}
你必須初始化使用相同的種子,並因此返回相同的值,以防止它被初始化一遍一遍所述方法外的Random
對象。
重要的是要注意到,作爲LukeH在評論中正確添加,那System.Random
類不線程安全的,不應該在單獨的線程任務之間共享是非常重要的。
您正在使用Random
類的兩個實例。使用parameterless constructor,隨機數發生器使用基於系統時鐘的值來播種。
這意味着如果您不斷創建兩個Random
實例,它們將使用相同的值進行初始化,因爲系統時鐘具有有限的分辨率。具有相同的種子意味着這兩個實例將產生相同的結果序列。
一些谷歌搜索顯示,使用Random
跨線程會導致其破裂,返回零的循環順序,因此,如果你要多線程代碼的這個特殊的一部分,您可能想看看this article如何創建一個Random
類的單線程安全版本。
doh,當然:) – danielovich 2013-04-11 09:02:49
正確,但是......要小心「System.Random」不是線程安全的,因此在多個線程池任務之間共享單個實例(通過Task.Run)不是一個好主意。 – LukeH 2013-04-11 09:03:08
@LukeH謝謝,我已經編輯了我的答案。 – 2013-04-11 09:05:57