web-dev-qa-db-fra.com

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

Erg, j'essaie de trouver ces deux méthodes dans la BCL à l'aide de Reflector, mais je ne peux pas les localiser. Quelle est la différence entre ces deux extraits?

UNE:

IEnumerable<string> items = ...

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

B:

IEnumerable<string> items = ...

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

Y a-t-il différentes conséquences d'utiliser l'un sur l'autre? (Supposons que tout ce que je fais dans les corps entre crochets des deux exemples est thread-safe.)

140
SnickersAreMyFave

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é, il est prévu d'effectuer une requête sur plusieurs threads, de combiner le résultat et de le renvoyer au thread appelant. Le code de l'instruction foreach reste donc toujours sur le thread d'interface utilisateur.

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

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

La différence est que B n'est pas parallèle. La seule chose que fait AsParallel(), c'est qu'elle entoure 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.

En passant, si vous souhaitez consulter les méthodes de Reflector, AsParallel() est dans la classe System.Linq.ParallelEnumerable De l’assemblage System.Core. Parallel.ForEach() est dans le mscorlib assembleur (espace de nom System.Threading.Tasks).

49
svick

La deuxième méthode ne sera pas parallèle la manière correcte d’utiliser AsParallel () dans votre exemple serait

IEnumerable<string> items = ...

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