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


143

Ehm, sto cercando di trovare questi due metodi nel BCL usando Reflector, ma non riesco a individuarli. Qual è la differenza tra questi due frammenti?

UN:

IEnumerable<string> items = ...

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

B:

IEnumerable<string> items = ...

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

Ci sono diverse conseguenze nell'usare l'una sull'altra? (Supponiamo che tutto ciò che sto facendo nei corpi tra parentesi di entrambi gli esempi sia thread-safe.)

Risposte:


148

Fanno qualcosa di completamente diverso.

Il primo prende il delegato anonimo ed esegue più thread su questo codice in parallelo per tutti i diversi elementi.

Il secondo non è molto utile in questo scenario. In breve, si intende eseguire una query su più thread, combinare il risultato e restituirlo al thread chiamante. Quindi il codice sull'istruzione foreach rimane sempre nel thread dell'interfaccia utente.

Ha senso solo se fai qualcosa di costoso nella query linq a destra della AsParallel()chiamata, come:

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

Qual è il vantaggio rispetto al semplice fare una foreach parallela sul computer compute?
l --''''''--------- '' '' '' '' '' ''

51

La differenza è che B non è parallela. L'unica cosa che AsParallel()fa è che si avvolge attorno a a IEnumerable, così che quando si usano i metodi LINQ, vengono utilizzate le loro varianti parallele. Il wrapper GetEnumerator()(che viene utilizzato dietro le quinte in foreach) restituisce anche il risultato della collezione originale GetEnumerator().

A proposito, se si desidera esaminare i metodi in Reflector, AsParallel()è nella System.Linq.ParallelEnumerableclasse System.Corenell'assieme. Parallel.ForEach()è mscorlibnell'assembly (spazio dei nomi System.Threading.Tasks).


Cosa intendi con ... Vengono usate le loro varianti parallele ...?
l --''''''--------- '' '' '' '' '' ''

2
@punctuation Che, ad esempio, quando scrivi .Select(), chiama ParallelEnumerable.Select()e non è normale Enumerable.Select().
svick,

50

Il secondo metodo non sarà parallelo al modo corretto di usare AsParallel () nel tuo esempio

IEnumerable<string> items = ...

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

3
Perché usare la combinazione di asparallelo insieme a forall anziché semplicemente foreach?
l --''''''--------- '' '' '' '' '' ''
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.