我用下面的例子总结了这个问题。
static List<double> values = new List<double>();
static void Main(string[] args)
{
doThis();
foreach (var value in values)
Console.WriteLine(value);
Console.ReadLine();
}
public static void doThis()
{
for (int i = 0; i < 100; i++)
{
double value = 0;
double sum = 0;
Random rnd = new Random();
for (int j = 0; j < 10; j++)
{
value = rnd.Next(0, 1000);
sum += value;
}
values.Add(sum / 10);
}
}
使用此代码,值列表会为所有索引返回相同的值。 values = {rnd,rnd,rnd,rnd ...,rnd}。不知何故,最后一个值会覆盖其他值。
但是,如果我逐步调试,它会显示不同的值:values = {rnd0,rnd1,rnd2 ....,rnd99}。
如果你启发我,我感激不尽。
答案 0 :(得分:6)
您需要创建一个唯一的Random
。如果您在很短的时间内创建了多个实例,他们很可能会返回相同的数字序列。
答案 1 :(得分:0)
我做过实验,看看博文:Random Number in MultiThreading
Random() - 它利用系统时钟作为种子值并创建实例。 随机在创建两个实例时使用系统时钟作为输入
Random rand = new Random();
Random rand1 = new Random();
使用相同的系统时钟输入,因此在执行以下代码
时输出如上 Console.WriteLine(rand.Next());
Console.WriteLine(rand1.Next());
生成相同的随机数。示例两行代码在控制台上写相同的值。
解决随机问题的解决方案:
保持随机功能
Random rnd = new Random();
for (int i = 0; i < 100; i++)
{
double value = 0;
double sum = 0;
for (int j = 0; j < 10; j++)
{
value = rnd.Next(0, 1000);
sum += value;
}
values.Add(sum / 10);
}
答案是,如果您尝试多线程方案,则有可能再次失败
例如
var task1 = Task.Factory.StartNew(()=> dothis());
var task2 = Task.Factory.StartNew(()=> dothis());
public static void doThis()
{
Random rnd = new Random();
for (int i = 0; i < 100; i++)
{
double value = 0;
double sum = 0;
for (int j = 0; j < 10; j++)
{
value = rnd.Next(0, 1000);
sum += value;
}
values.Add(sum / 10);
}
}
如果有人尝试这样,那么(1)我给出答案的情况也会失败,因为两个线程都创建Random
具有相同的种子值。