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);
プログラムは期待どおりに実行されます (配列は完全に満たされています)。
ここで何が問題になる可能性がありますか?
前もって感謝します。