2010-09-24 6 views
126

Erg, j'essaie de trouver ces deux méthodes dans la BCL en utilisant Reflector, mais je ne peux pas les localiser. Quelle est la différence entre ces deux extraits?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()) 
{ 
    ... 
} 

Y at-il des conséquences différentes de l'utilisation d'un sur l'autre? (On suppose que tout ce que je fais dans le corps entre crochets des deux exemples est thread-safe.)

Répondre

138

Ils font quelque chose de tout à fait différent.

Le premier prend le délégué anonyme et exécute plusieurs threads sur ce code en parallèle pour tous les différents éléments.

Le deuxième pas très utile dans ce scénario. En un mot, il est destiné à faire une requête sur plusieurs threads, et combiner le résultat, et le donner à nouveau au thread appelant. Le code de l'instruction foreach reste donc toujours sur le thread de l'interface utilisateur.

Il est logique si vous faites quelque chose de cher dans la requête LINQ à droite de l'appel AsParallel(), comme:

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

Quel est l'avantage sur tout simplement faire un foreach parallèle sur le computefibonacci? –

46

La différence est, B n'est pas parallèle. La seule chose que fait AsParallel() est qu'il enveloppe un IEnumerable, de sorte que lorsque vous utilisez des méthodes LINQ, leurs variantes parallèles sont utilisées. Le GetEnumerator() du wrapper (qui est utilisé dans les coulisses du foreach) renvoie même le résultat du GetEnumerator() de la collection d'origine.

BTW, si vous voulez regarder les méthodes dans Reflector, AsParallel() est dans la classe System.Linq.ParallelEnumerable dans l'ensemble System.Core. Parallel.ForEach() est dans l'assembly mscorlib (espace de noms System.Threading.Tasks).

+0

Que voulez-vous dire par ... Leurs variantes parallèles sont utilisées ...? –

+1

@punctuation Par exemple, lorsque vous écrivez '.Select()', il appelle 'ParallelEnumerable.Select()' et non 'Enumerable.Select()'. – svick

42

La deuxième méthode ne sera pas parallèle à la bonne façon d'utiliser AsParallel() dans votre exemple serait

IEnumerable<string> items = ... 

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

Pourquoi utiliser la combinaison de asparallel avec forall au lieu de simplement foreach? –

Questions connexes