新しい C# 4.0 関数を使用して、オブジェクトのリストに対して並列関数を実行しようとしていますParallel.ForEach
。これは非常に長いメンテナンス プロセスです。リストの順序で実行し、前のポイントで停止して実行を続行できるようにしたいと思います。どうすればよいでしょうか。
以下に例を示します。オブジェクトのリストがあります: a1 to a100
。現在の順序は次のとおりです:
a1, a51, a2, a52, a3, a53...
この注文をお願いします:
a1, a2, a3, a4...
一部のオブジェクトが順序どおりに実行されなくても構いませんが、リスト内でその時点より前のすべてのオブジェクトが実行されたと言えるポイントが見つかれば問題ありません。並列プログラミングの Csharp ホワイトペーパーを読みましたが、これについては何も見つかりませんでした。クラスにはこれに関する設定はありませんParallelOptions
。
ベストアンサー1
次のようにします。
int current = 0;
object lockCurrent = new object();
Parallel.For(0, list.Count,
new ParallelOptions { MaxDegreeOfParallelism = MaxThreads },
(ii, loopState) => {
// So the way Parallel.For works is that it chunks the task list up with each thread getting a chunk to work on...
// e.g. [1-1,000], [1,001- 2,000], [2,001-3,000] etc...
// We have prioritized our job queue such that more important tasks come first. So we don't want the task list to be
// broken up, we want the task list to be run in roughly the same order we started with. So we ignore tha past in
// loop variable and just increment our own counter.
int thisCurrent = 0;
lock (lockCurrent) {
thisCurrent = current;
current++;
}
dothework(list[thisCurrent]);
});
並列 for ループから抜け出すときに、すべてのスレッドが終了してから抜け出すと仮定すると、最後に実行されるリスト項目がわかることがわかります。私は PLINQ や LINQ の大ファンではありません。正直なところ、LINQ/PLINQ を記述することで、ソース コードの保守性や可読性が向上するとは思えません... Parallel.For の方がはるかに優れたソリューションです。