Parallel.ForEach () vs. foreach (IEnumerable <T> .AsParallel ())


143

Erg, ich versuche, diese beiden Methoden mit Reflector in der BCL zu finden, kann sie aber nicht finden. Was ist der Unterschied zwischen diesen beiden Schnipsel?

EIN:

IEnumerable<string> items = ...

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

B:

IEnumerable<string> items = ...

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

Gibt es unterschiedliche Konsequenzen bei der Verwendung übereinander? (Angenommen, alles, was ich in den Klammern beider Beispiele mache, ist threadsicher.)

Antworten:


148

Sie machen etwas ganz anderes.

Der erste nimmt den anonymen Delegaten und führt mehrere Threads für diesen Code parallel für alle verschiedenen Elemente aus.

Der zweite ist in diesem Szenario nicht sehr nützlich. Kurz gesagt, es ist beabsichtigt, eine Abfrage für mehrere Threads durchzuführen, das Ergebnis zu kombinieren und es erneut an den aufrufenden Thread weiterzugeben. Der Code in der foreach-Anweisung bleibt also immer im UI-Thread.

Es ist nur sinnvoll, wenn Sie in der Linq-Abfrage rechts neben dem AsParallel()Aufruf etwas Teueres tun , wie:

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

Was ist der Vorteil, wenn Sie einfach eine parallele foreach für die computefibonacci durchführen?
l - '' '' '

51

Der Unterschied ist, dass B nicht parallel ist. Das einzige, was AsParallel()Sie tun müssen, ist, dass es um a gewickelt wird IEnumerable, sodass bei Verwendung von LINQ-Methoden deren parallele Varianten verwendet werden. Der Wrapper GetEnumerator()(der hinter den Kulissen in verwendet wird foreach) gibt sogar das Ergebnis der ursprünglichen Sammlung zurück GetEnumerator().

Übrigens, wenn Sie sich die Methoden in Reflector ansehen möchten, AsParallel()befindet sich in der System.Linq.ParallelEnumerableKlasse in der System.CoreAssembly. Parallel.ForEach()befindet sich in der mscorlibAssembly (Namespace System.Threading.Tasks).


Was meinst du mit ... Ihre parallelen Varianten werden verwendet ...?
l - '' '' '

2
@punctuation Das heißt zum Beispiel, wenn Sie schreiben .Select(), es ruft ParallelEnumerable.Select()und nicht das normale Enumerable.Select().
Svick

50

Die zweite Methode ist nicht parallel. Die korrekte Verwendung von AsParallel () in Ihrem Beispiel wäre

IEnumerable<string> items = ...

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

3
Warum sollte man die Kombination von asparallel zusammen mit forall verwenden, anstatt einfach foreach?
l - '' '' '
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.