TPL 数据并行问题

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

我有一个情况是要并行处理这组数据,最后我想知道总共有多少数据已经处理成功。我按照 http://msdn.microsoft.com/en-us/library/dd460703.aspxhttps://web.archive.org/web/20230128065739/http 中的示例提供了以下虚拟代码: //reedcopsey.com/2010/01/22/parallelism-in-net-part-4-imperative-data-parallelism-aggregation/

    public void DoWork2()
    {
        int sum = 0;
        Parallel.For<int>(0, 10,
            () => 0,
            (i, lockState, localState) =>
            {
                DummyEntity entity = DoWork3(i);
                if (entity != null)
                {
                    Console.WriteLine("Processed {0}, sum need to be increased by 1.", i);
                    return 1;
                }
                else
                {
                    Console.WriteLine("Processed {0}, sum need to be increased by 0.", i);
                    return 0;
                }
            },
            localState =>
            {
                lock (syncRoot)
                {
                    Console.WriteLine("Increase sum {0} by {1}", sum, localState);
                    sum += localState;
                }
            }
            );
        Console.WriteLine("Total items {0}", sum);
    }

    private DummyEntity DoWork3(int i)
    {
        if (i % 2 == 0)
        {
            return new DummyEntity();
        }
        else
        {
            return null;
        }
    }

但是每次跑步的结果都会改变。我认为代码有问题。但不明白为什么。

c# .net-4.0 task-parallel-library
1个回答
2
投票

你的问题是你对过载的选择。您已存储本地状态信息以最大程度地减少全局状态的使用,但您并未使用本地状态。

如果您从给出的示例中注意到,他们在循环体中使用了小计(您所说的

localState
):

subtotal += nums[j];
return subtotal;

将其与您的代码进行比较(更加简洁):

if (entity != null)
{
    return 1;
}
else
{
    return 0;
}

没有提到

localState
,所以你实际上已经抛弃了一些答案。如果您将其更改为:

if (entity != null)
{
    return localState + 1;
}
else
{
    return localState;
}

您将在命令行上找到以下答案(对于这个给定的问题):

Total items 5

使用本地状态是为了减少对共享状态的访问。

这是使用 0..50 作为范围的片段:

Processed 22, sum need to be increased by 1.
Processed 23, sum need to be increased by 0.
Increase sum 0 by 1
Processed 8, sum need to be increased by 1.
Processed 9, sum need to be increased by 0.
Processed 10, sum need to be increased by 1.
Processed 11, sum need to be increased by 0.
Increase sum 1 by 2
Increase sum 3 by 8
Increase sum 11 by 10
Processed 16, sum need to be increased by 1.
Processed 17, sum need to be increased by 0.
Processed 18, sum need to be increased by 1.
Increase sum 21 by 4
Total items 25
© www.soinside.com 2019 - 2024. All rights reserved.