1

C# での並列プログラミングに関する教科書の例に取り組みました。この本は、Parallel.Invoke がタスクの作成、呼び出し、および待機を置き換えることができることを示唆しています。ただし、Parallel.Invoke を使用すると、値を返す前にタスクが終了しないことがわかりました。しかし理論的には、Parallel.Invoke は常に待機する必要があります。

コード:

    private byte[] getDataForGraph(int dataSize)
    {
        byte[] data = new byte[dataSize];


        Parallel.Invoke(
            () => Task.Factory.StartNew(() => generateGraphData(data, 0, pixelWidth / 8)),
            () => Task.Factory.StartNew(() => generateGraphData(data, pixelWidth / 8,
                pixelWidth / 4)),
            () => Task.Factory.StartNew(() => generateGraphData(data, pixelWidth / 4,
                pixelWidth * 3 / 8)),
            () => Task.Factory.StartNew(() => generateGraphData(data, pixelWidth * 3 / 8,
                pixelWidth / 2)));

        return data;
    }

そして、関数を実行する方法:

Task<byte[]> getDataTask = Task<byte[]>.Factory.StartNew(() => getDataForGraph(dataSize));
byte[] data = getDataTask.Result;

これprivate void generateGraphData(byte[] data, int partitionStart, int partitionEnd)は、partitionStart から partitionEnd までのデータ配列を埋める関数です。

プログラムを実行すると、配列の一部だけが埋められます。しかし、Invokeを次のように置き換えると

Task first = Task.Factory.StartNew(() => generateGraphData(data, 0, pixelWidth / 8));
Task second = Task.Factory.StartNew(() => generateGraphData(data, pixelWidth / 8, pixelWidth / 4));
Task third = Task.Factory.StartNew(() => generateGraphData(data, pixelWidth / 4, pixelWidth * 3 / 8));
Task fourth = Task.Factory.StartNew(() => generateGraphData(data, pixelWidth * 3 / 8, pixelWidth / 2));
Task.WaitAll(first, second, third, fourth);

プログラムは期待どおりに実行されます (配列は完全に満たされています)。

ここで何が問題になる可能性がありますか?

前もって感謝します。

4

1 に答える 1

5

完了するまでアクションを実行します。あなたの場合、各アクションは呼び出すことですTask.Factory.StartNew(...)-そしてそれは完了しました; ただし、これらのタスクのそれぞれがまだキューに入れられている/処理されているという保証はありません。違いはWaitAll(あなたのParallel例では呼び出していない)です。

ここでの 1 つのオプションは、これを次のように減らすことです。

Parallel.Invoke(
    () => generateGraphData(data, 0, pixelWidth / 8),
    () => generateGraphData(data, pixelWidth / 8, pixelWidth / 4),
    () => generateGraphData(data, pixelWidth / 4, pixelWidth * 3 / 8),
    () => generateGraphData(data, pixelWidth * 3 / 8, pixelWidth / 2)
);
于 2010-07-31T07:39:18.997 に答える