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();
}
}
}