我写了一个简单的Parallel.For循环。但是,当我运行代码时,会得到随机结果。我希望var total为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);
}
}
}
答案 0 :(得分:4)
代替使用
(i, status, y) =>
{
return i;
}
您应该使用
(i, status, y) =>
{
return y + i;
}
Parallel.For
将源序列分成几个分区。每个分区中的项目均按顺序处理,但可以并行执行多个分区。
每个分区都有一个本地状态。本地状态是上述lambda函数的返回值,它也作为y
参数传递。因此,返回y + i
的原因现在应该很清楚:您应该将本地状态更新为先前状态和输入值i
的和。
处理完分区的每个项目之后,本地状态的最终值将传递到最后一个函数,您可以在其中汇总所有状态:
(x) =>
{
Interlocked.Add(ref total, x);
}