Parallel.For <int>不能按预期工作

时间:2018-09-02 05:59:30

标签: c# .net parallel-processing

我写了一个简单的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);
        }
    }
}

1 个答案:

答案 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);
}