2010-09-24 11 views
126

Erg, estoy tratando de encontrar estos dos métodos en el BCL usando Reflector, pero no puedo localizarlos. ¿Cuál es la diferencia entre estos dos fragmentos?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()) 
{ 
    ... 
} 

¿Hay diferentes consecuencias del uso de uno sobre el otro? (Supongamos que todo lo que hago en los cuerpos entre corchetes de ambos ejemplos es seguro para hilos.)

Respuesta

138

Hacen algo bastante diferente.

El primero toma el delegado anónimo y ejecuta varios hilos en este código en paralelo para todos los elementos diferentes.

El segundo no es muy útil en este escenario. En pocas palabras, está destinado a hacer una consulta sobre múltiples hilos, y combinar el resultado, y darle nuevamente a la cadena de llamada. Entonces, el código en la declaración foreach permanece siempre en el hilo de la interfaz de usuario.

Sólo tiene sentido si se hace algo caro en la consulta LINQ a la derecha de la llamada AsParallel(), como:

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

Cuál es el beneficio más simplemente haciendo un foreach paralelo en el computefibonacci? –

46

La diferencia es que B no es paralela. Lo único que hace AsParallel() es que se ajusta a IEnumerable, de modo que cuando utiliza los métodos LINQ, se usan sus variantes paralelas. El contenedor GetEnumerator() (que se utiliza detrás de las escenas en el foreach) incluso devuelve el resultado de la colección original GetEnumerator().

Por cierto, si quiere ver los métodos en Reflector, AsParallel() está en la clase System.Linq.ParallelEnumerable en el ensamblaje System.Core. Parallel.ForEach() se encuentra en el ensamblaje mscorlib (espacio de nombres System.Threading.Tasks).

+0

¿Qué quiere decir con ... Sus variantes paralelas se utilizan ...? –

+1

@punctuation Eso, por ejemplo, cuando escribe '.Select()', llama 'ParallelEnumerable.Select()' y no el 'Enumerable.Select()' normal. – svick

42

El segundo método no será paralela a la forma correcta de utilizar AsParallel() en su ejemplo sería

IEnumerable<string> items = ... 

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

¿Por qué usar la combinación de asparalela junto con forall en lugar de simplemente foreach? –

Cuestiones relacionadas