2017-03-15 5 views
8

Parallel.ForEach()MaxDegreeOfParallelism==1は、入力可能な順序で入力を処理することが保証されていますか?Parallel.ForEachはMaxDegreeOfParallelism = 1で順番に処理されますか?

答えが「いいえ」の場合、この動作を強制する方法はありますか? MSDNから

+0

これは良い質問です。答えはドキュメントに基づいていると思います。 https://msdn.microsoft.com/en-us/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism(v=vs.110).aspxあなたはいつもいくつかのテストケースをスピンアップし、検証することができます。 – mituw16

+4

なぜこれを知りたいのですか?単に学問的な好奇心、あるいは実世界の問題を経験していますか? – mason

+1

@ mituw16:リンクされたMSDNの記事でこれに関するヒントが見つかりません。また、いくつかのテストをスピンアップすることは、「はい」の保証ではありません。 –

答えて

3

Parallel.ForEach方法は、実行順序を保証するものではありません。シーケンシャルForEachループとは異なり、着信値は必ずしも順番に処理されるわけではありません。

https://msdn.microsoft.com/library/ff963552.aspx

10

まず、Microsoft's official documentation on parallel programming実行順序がを保証されていないと述べていることが正しいです。

Parallel.ForEachメソッドは実行の順序を保証しません。シーケンシャルForEachループとは異なり、着信値は必ずしも順番に処理されるわけではありません。並列的内の項目を処理するために

これは公開APIが設計されてParallel.ForEachを使用するのがベストでしょう。アイテムを順次処理する必要がある場合は、通常のforeachループを使用するほうがずっと良いでしょう。その目的は、MaxDegreeOfParallelism = 1を使用するよりも明確です。

これは好奇心のため、.NET 4.7.1のソースコードを見てきました。短い答えはです。MaxDegreeOfParallelism = 1の場合、アイテムは順次処理されます。ただし、これは必ずしもこのような方法ではない可能性があるため、将来の実装ではこれを頼りにするべきではありません。

Parallel.ForEachを見てみると、それを通じ、以下の、あなたは最終的に(このプロセスは、それがTSource[]List<TSource>、またはIEnumerable<TSource>であるかどうかは若干異なる繰り返し処理されるコレクションが分割されていることがわかります。

Task.SavedStateForNextReplicaTask.SavedStateFromPreviousReplicaを並行して実行中のタスク間の状態を通信するためにParallelForReplicaTaskでオーバーライドされている。この場合、それらはタスクが反復処理すべきパーティションの通信に使用されている。

最後に、のはTask.ExecuteSelfReplicatingを見てみましょう。ParallelForReplicatingTaskは、指定された並列度とタスクスケジューラのMaximumConcurrencyLevelに基づいてShouldReplicateを上書きします。したがって、これはMaxDegreeOfParallelism = 1で、1つの子タスクしか作成されません。そのため、このタスクは作成された単一のパーティションでのみ動作します。

だから、あなたの質問に答えるために:書き込みのように、MaxDegreeOfParallism = 1Parallel.ForEachはわずかに異なるパスがIEnumerable<TSource>をキャストできるかどうかに応じて、IEnumerable<TSource>ためIList<TSource>ためTSource[]from beginning to end、およびuse GetEnumeratorのためのコレクションfrom beginning to endを列挙しますOrderablePartitioner<TSource>に送信してください。これらの3つのパスはParallel.ForEachWorkerで決まります。

あなた自身で見たい場合は、ソースコードを参照することを強くお勧めします。

これはあなたの質問に答えることができますが、覚えておくことは本当に重要です。には依存しません。この実装が将来変更される可能性は非常に高いです。

関連する問題