我写了一个简单的Parallel.For循环。但是当我运行代码时,我会得到随机结果。我预计var总数为15(1 + 2 + 3 + 4 + 5)。我使用Interlocked.Add来防止竞争条件和奇怪的行为。有人可以解释为什么输出是随机的而不是15?
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("before Dowork");
DoWork();
Console.WriteLine("After Dowork");
Console.ReadLine();
}
public static void DoWork()
{
try
{
int total = 0;
var result = Parallel.For<int>(0, 6,
() => 0,
(i, status, y) =>
{
return i;
},
(x) =>
{
Interlocked.Add(ref total, x);
});
if (result.IsCompleted)
Console.WriteLine($"total is: {total}");
else Console.WriteLine("loop not ready yet");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
而不是使用
(i, status, y) =>
{
return i;
}
你应该使用
(i, status, y) =>
{
return y + i;
}
Parallel.For
将源序列分成几个分区。按顺序处理每个分区中的项目,但可以并行执行多个分区。
每个分区都有一个本地状态。本地状态是上述lambda函数的返回值,它也作为y
参数传递。所以返回y + i
的原因现在应该清楚了:你应该将本地状态更新为前一个状态和输入值i
的总和。
在处理了分区的每个项目之后,将本地状态的最终值传递给最后一个函数,在该函数中汇总所有状态:
(x) =>
{
Interlocked.Add(ref total, x);
}