1

データのセットを並行して処理する状況があります。最終的に、正常に処理されたデータの合計数を知りたいです。http://msdn.microsoft.com/en-us/library/dd460703.aspxおよびhttp://reedcopsey.com/2010/01/22/parallelism-in-netのサンプルに従って、次のダミー コードが付属しています。 -part-4-命令型データ並列処理集計/

    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;
        }
    }

ただし、実行するたびに結果が変わります。コードに何か問題があると思います。しかし、理由を理解できませんでした。

4

1 に答える 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
于 2013-01-16T17:56:22.473 に答える