C#Random。下一步突然停止返回随机值

C#Random。下一步突然停止返回随机值,c#,random,c#-4.0,return-value,C#,Random,C# 4.0,Return Value,可能重复: 我正在重构和扩展一个基于C#agent的小型模型,以帮助一些生物学教授预测疾病的传播。在每年的模拟中,每个个体都会随机前往附近的一个种群节点,可能会传播疾病。我是C#的新手,但我读过Random的潜在问题。接下来,如果使用相同的系统时间重新初始化,则返回相同的值。为了避免这种情况,我创建了一个静态实例,它为每个新的随机值引用 具体内容: 在扩展模型的过程中,我对模型进行了修改,以并行计算每个人口节点的“旅行”信息。在测试模型时,我注意到在新版本中,疾病在第一年后不会传播。进一步的调

可能重复:

我正在重构和扩展一个基于C#agent的小型模型,以帮助一些生物学教授预测疾病的传播。在每年的模拟中,每个个体都会随机前往附近的一个种群节点,可能会传播疾病。我是C#的新手,但我读过Random的潜在问题。接下来,如果使用相同的系统时间重新初始化,则返回相同的值。为了避免这种情况,我创建了一个静态实例,它为每个新的随机值引用

具体内容:


在扩展模型的过程中,我对模型进行了修改,以并行计算每个人口节点的“旅行”信息。在测试模型时,我注意到在新版本中,疾病在第一年后不会传播。进一步的调查将问题缩小到节点之间的移动。第一年后,所有特工都一动不动。我检查了负责它们旅行的函数,发现它通过创建所有附近节点的列表来工作,生成一个随机数我怀疑您在多个线程中同时使用了相同的
random
实例。不要这样做-这不是线程安全的

选项:

  • 为每个线程创建一个新的
    Random
    ThreadStatic
    可以在这里提供帮助)
  • 使用
    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,那么还有一个类,它有助于简化每个线程初始化一个实例。

我认为您应该改用RNGCryptoServiceProvider


随机
对象不是线程安全的。为了避免这种情况,您可以使用以下代码:


您也可以使用
RNGCryptoServiceProvider
,它是线程安全的,还可以生成更好的随机数据。

一个简短但完整的代码示例可以重现错误,这将有助于您和SO社区帮助您诊断问题。我问了一个我认为相关且可能有帮助的问题:
class ThreadSafeRandom 
{ 
    private static Random random = new Random(); 

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