的Parallel.For 没有按预期工作

问题描述 投票:0回答:1

我写了一个简单的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);
        }
    }
}
c# .net parallel-processing
1个回答
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);
}
© www.soinside.com 2019 - 2024. All rights reserved.