2010-09-24 11 views
126

Erg, ich versuche, diese beiden Methoden in der BCL mit Reflector zu finden, kann sie aber nicht finden. Was ist der Unterschied zwischen diesen beiden Schnipsel?Parallel.ForEach() vs. foreach (IEnumerable <T>. AsParallel())

A:

IEnumerable<string> items = ... 

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

B:

IEnumerable<string> items = ... 

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

Gibt es verschiedene Folgen von übereinander verwenden? (Angenommen, was auch immer ich in den Klammern in beiden Beispielen mache, ist fadensicher.)

Antwort

138

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.

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

Es macht nur Sinn, wenn Sie etwas teuer in der Linq-Abfrage auf der rechten Seite des AsParallel() Telefonierens, wie:

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

Was ist der Vorteil gegenüber einfach tun, eine parallele foreach auf dem computefibonacci wäre? –

46

Der Unterschied ist, ist B nicht parallel sind. Das einzige, was AsParallel() tut, ist, dass es eine IEnumerable umschließt, so dass, wenn Sie LINQ-Methoden verwenden, ihre parallelen Varianten verwendet werden. Der Wrapper GetEnumerator() (der hinter den Kulissen in der foreach verwendet wird) gibt sogar das Ergebnis der ursprünglichen Sammlung GetEnumerator() zurück.

BTW, wenn Sie die Methoden in Reflector betrachten möchten, ist AsParallel() in der System.Linq.ParallelEnumerable Klasse in der System.Core Baugruppe. Parallel.ForEach() ist in der mscorlib Assembly (Namespace System.Threading.Tasks).

+0

Was meinst du mit ... Ihre parallelen Varianten werden verwendet ...? –

+1

@punctuation Wenn Sie zum Beispiel '.Select()' schreiben, ruft es 'ParallelEnumerable.Select()' auf und nicht das normale 'Enumerable.Select()'. – svick

42

Die zweite Methode wird nicht die richtige Art und Weise parallel sein zu verwenden AsParallel() in Ihrem Beispiel

IEnumerable<string> items = ... 

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

Warum verwenden Sie die Kombination von asparallel zusammen mit forall anstatt einfach foreach? –