2010-07-07 48 views
5

可能重複:
System.Random keeps on returning the same valueC#Random.Next突然停止返回隨機值

我重構和擴大小C#基於代理的模型,以幫助一些生物學教授預測傳播疾病。模擬每一年,每個個體代理人隨機前往附近的一個人口節點,可能會傳播疾病。我是C#的新手,但是我已經閱讀了有關使用相同系統時間重新初始化時Random.Next返回相同值的潛在問題。爲了避免這種情況,我創建了一個爲每個新隨機值引用的靜態實例。

的細節:

在我的努力,以擴大我已經改變了它來計算並行每個人口節點「旅行」的信息模型。在對模型進行測試時,我注意到在新版本中,疾病不會蔓延到第一年。進一步的調查將問題縮小到節點之間的旅行。在第一年之後,所有的特工都保持不動。我檢查了負責他們旅行的功能,發現它的工作方式是創建一個所有附近節點的列表,生成一個隨機數< =列表中元素的數量,並前往listOfNearbyNodes [myRandomNumber]。

問題:

我再補充一個print語句輸出爲每次迭代隨機指數值。我發現整個模型在模擬的第一年完全符合預期,隨機數在可接受的範圍內生成。但是,在第一年結束並且模擬循環之後,完全相同的代碼將僅返回0的「隨機」索引。每個線程,每次迭代,每個節點,每個代理始終爲0.由於代理的當前節點始終列表中的第一個項目代理不再移動。我認爲這可能是系統時間種子錯誤的另一種表現,所以我嘗試了三種不同的方式來實現一個靜態隨機對象,但它沒有幫助。每次運行模擬時,第一年總能正常工作,然後Random.Next()開始只返回0。

有沒有人有想法,我應該看看下一個錯誤?謝謝!

+2

一個簡短但完整的代碼示例重現錯誤將有助於您和SO社區幫助您診斷問題。 – LBushkin 2010-07-07 16:04:38

+0

我問了一個我認爲是相關的問題,可能有所幫助:http://stackoverflow.com/questions/2924599/parallel-loops-and-random-produce-odd-results – Mathias 2010-07-07 16:09:17

+0

重複的[System.Random不斷返回相同的值](http://stackoverflow.com/questions/295900/system-random-keeps-on-returning-the-same-value)。 – 2010-07-07 16:11:02

回答

18

我懷疑你在多個線程中同時使用同一個Random實例。不要那樣做 - 它不是線程安全的。

選項:

  • 創建的每個線程Random一個新實例(ThreadStatic可以幫助這裏)
  • 使用單一實例的Random,但永遠只能用它的鎖。

我有一個blog post與一些示例代碼,但請閱讀評論,以及有很好的建議,以改善它。我打算在近乎未來的某個時候寫另一篇關於隨機性的文章......

+0

謝謝,這正是我需要的! – Mandelbrot 2010-07-07 17:13:13

5

我不相信隨機類被設計爲線程安全的(可以從多個線程同時使用) - 所以如果你以這種方式共享一個實例,你可能會破壞隨機生成器的狀態,阻止其正常運行。

可以裝飾保存的參考Random類爲ThreadStatic,這將讓你保持每個線程單獨的實例靜態變量:

[ThreadStatic] 
private static Random m_Random; // don't attempt to initialize this here... 

public void YourThreadStartMethod() 
{ 
    // initialize each random instance as each thread starts... 
    m_Random = new Random(); 
} 

如果你使用.NET 4.0,有還有ThreadLocal<T>類,這有助於更簡單地爲每個線程初始化一個實例。

2

Random對象不是線程安全的。要解決這個問題,你可以使用這個代碼this answer被盜:

class ThreadSafeRandom 
{ 
    private static Random random = new Random(); 

    public static int Next() 
    { 
     lock (random) 
     { 
      return random.Next(); 
     } 
    } 
} 

您也可以使用RNGCryptoServiceProvider,這是線程安全的,並且還產生更好的隨機數據。