142 votes

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

Erg, j'essaie de trouver ces deux méthodes dans la BCL en utilisant Reflector, mais je n'arrive pas à les localiser. Quelle est la différence entre ces deux extraits ?

A :

IEnumerable<string> items = ...

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

B :

IEnumerable<string> items = ...

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

Y a-t-il des conséquences différentes à utiliser l'un plutôt que l'autre ? (Supposez que ce que je fais dans les corps entre parenthèses des deux exemples est thread safe).

153voto

Ils font quelque chose de très 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 second n'est pas très utile dans ce scénario. En résumé, elle est destinée à effectuer une requête sur plusieurs threads, à combiner le résultat et à le redonner au thread appelant. Ainsi, le code de l'instruction foreach reste toujours sur le thread de l'interface utilisateur.

Cela n'a de sens que si vous faites quelque chose de coûteux dans la requête linq à droite de l'élément AsParallel() appeler, comme :

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

50voto

svick Points 81772

La différence est que B n'est pas parallèle. La seule chose AsParallel() est qu'il s'enroule autour d'une IEnumerable de sorte que lorsque vous utilisez des méthodes LINQ, leurs variantes parallèles sont utilisées. La fonction GetEnumerator() (qui est utilisé en coulisses dans le foreach ) renvoie même le résultat de l'analyse de la collection originale. GetEnumerator() .

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

49voto

Scott Chamberlain Points 32782

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

IEnumerable<string> items = ...

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X