我正在学习C#中的异步编程,并编写此代码来测试任务并行库(控制台应用程序):
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
var opr1 = new SlowOperation();
var opr2 = new SlowOperation();
//TASK
Console.WriteLine("Started processing using TASK. Start: {0}", sw.Elapsed);
sw.Start();
Task.Factory.StartNew(() => opr1.PerformSlowOperation(1));
Task.Factory.StartNew(() => opr2.PerformSlowOperation(2));
Console.WriteLine("Stopped processing using TASK. Stop: {0}", sw.Elapsed);
sw.Stop();
}
慢速操作:
public class SlowOperation
{
public void PerformSlowOperation(int id)
{
var rand = new Random();
double sum = 0;
for (int i = 0; i < 100000000; i++)
{
var number = Convert.ToDouble(rand.Next(100)) / 100;
sum += number;
}
Console.WriteLine("Finished processing operation no. {0}. Final sum calculated is: {1}", id, sum.ToString("0.##"));
}
}
有谁能帮助我理解为什么SlowOperation类的每个实例产生的总和完全相同?
答案 0 :(得分:2)
Random
根据低分辨率的时间播种。这是一个经典问题,在我看来,这是一个API设计错误。我认为这已经在CoreCLR回购中发生了变化。
new Random().Next() == new Random().Next()
几乎总是如此。
另请注意,问题中95%的代码与问题无关。将来,您可以自己简化代码,直到只留下随机调用。这可以让你自己找到这些问题。
答案 1 :(得分:2)
在每项任务中使用不同的种子值进行设置。例如:
var rand = new Random(new System.DateTime().Millisecond + id);
随机指导员:https://msdn.microsoft.com/pt-br/library/ctssatww(v=vs.110).aspx
如果您的应用程序需要不同的随机数序列,请调用 这个构造函数反复使用不同的种子值。一种方法 产生一个独特的种子值是为了使它与时间有关。例如, 从系统时钟导出种子值。但是,系统时钟 可能没有足够的分辨率来提供不同的调用 此构造函数具有不同的种子值。