En parallèle.ForEach() vs foreach(IEnumerable<T>.AsParallel())
Erg, j'essaie de trouver ces deux méthodes dans la BCL en utilisant un Réflecteur, mais ne peut pas les localiser. Quelle est la différence entre ces deux extraits?
Un:
IEnumerable<string> items = ...
Parallel.ForEach(items, item => {
...
});
B:
IEnumerable<string> items = ...
foreach (var item in items.AsParallel())
{
...
}
Quelles sont les différentes conséquences de l'utilisation de l'un sur l'autre? (À supposer que tout ce que je fais entre crochets dans le corps de ces deux exemples est thread-safe.)
Vous devez vous connecter pour publier un commentaire.
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 second n'est pas très utile dans ce scénario. En un mot, il est prévu de faire une requête sur plusieurs threads, et combiner le résultat, et donnez-le à nouveau pour le thread appelant. Ainsi, le code de l'instruction foreach reste toujours sur le thread d'INTERFACE utilisateur.
Il n'a de sens que si vous faites quelque chose de cher dans la requête linq pour le droit de la
AsParallel()
appel, comme:La différence, c'est que B n'est pas parallèle. La seule chose
AsParallel()
n'est qu'il s'enroule autour d'unIEnumerable
, de sorte que lorsque vous utilisez LINQ méthodes, leurs parallèle les variantes sont utilisées. Le wrapper deGetEnumerator()
(qui est utilisé dans les coulisses de laforeach
) même renvoie le résultat de la collection originale deGetEnumerator()
.BTW, si vous voulez regarder les méthodes de Réflecteur,
AsParallel()
est dans leSystem.Linq.ParallelEnumerable
classe dans leSystem.Core
de l'assemblée.Parallel.ForEach()
est dans lemscorlib
assemblée (espace de nomsSystem.Threading.Tasks
)..Select()
, il appelleParallelEnumerable.Select()
et pas normalEnumerable.Select()
.La deuxième méthode ne sera pas en parallèle la façon correcte d'utiliser AsParallel() dans votre exemple serait