Parallel.ForEach()とforeach(IEnumerable <T> .AsParallel())の比較


143

Erg、私はReflectorを使用してBCLでこれら2つのメソッドを見つけようとしていますが、見つけることができません。これら2つのスニペットの違いは何ですか?

A:

IEnumerable<string> items = ...

Parallel.ForEach(items, item => {
   ...
});

B:

IEnumerable<string> items = ...

foreach (var item in items.AsParallel())
{
   ...
}

どちらを使用するかによって異なる影響はありますか?(両方の例の括弧で囲まれた本文で私がしていることはすべてスレッドセーフであると仮定します。)

回答:


148

彼らはかなり違うことをします。

最初のものは匿名のデリゲートを受け取り、すべての異なるアイテムに対してこのコードで複数のスレッドを並行して実行します。

2番目のものは、このシナリオではあまり役に立ちません。簡単に言えば、複数のスレッドでクエリを実行し、結果を組み合わせて、呼び出し元のスレッドに再度渡すことを目的としています。そのため、foreachステートメントのコードは常にUIスレッドに残ります。

AsParallel()呼び出しの右側のlinqクエリで次のような高額なことを行う場合にのみ意味があります。

 var fibonacciNumbers = numbers.AsParallel().Select(n => ComputeFibonacci(n));

コンピューティングフィボナッチで並列foreachを実行するだけの利点は何ですか?
l --''''''--------- '' '' '' '' '' ''

51

違いは、Bが平行でないことです。唯一のことAsParallel()は、をラップIEnumerableすることです。そのため、LINQメソッドを使用すると、それらの並列バリアントが使用されます。ラッパーGetEnumerator()(の背後で使用されforeachます)は、元のコレクションの結果も返しますGetEnumerator()

あなたはリフレクターのメソッドを見たい場合はところで、AsParallel()である System.Linq.ParallelEnumerableに、クラスSystem.Coreのアセンブリ。Parallel.ForEach()であるmscorlibアセンブリ(名前空間System.Threading.Tasks)。


どういう意味ですか...並列バリアントが使用されています...?
l --''''''--------- '' '' '' '' '' ''

2
@punctuationたとえば、を書くと、通常ではなくが.Select()呼び出されます。ParallelEnumerable.Select()Enumerable.Select()
2017

50

2番目のメソッドは並列ではありません。例でAsParallel()を使用する正しい方法は次のとおりです。

IEnumerable<string> items = ...

items.AsParallel().ForAll(item =>
{
    //Do parallel stuff here
});

3
単にforeachの代わりにasparallelとforallの組み合わせを使用するのはなぜですか?
l --''''''--------- '' '' '' '' '' ''
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.