web-dev-qa-db-fra.com

AsParallel.ForAll vs Parallel.ForEach

Y a-t-il une différence entre les extraits de code ci-dessous. Si oui, quoi?

myList.AsParallel().ForAll(i => { /*DO SOMETHING*/ });

et

Parallel.ForEach(mylist, i => { /*DO SOMETHING*/ });

Le thread principal attendra-t-il que tous les threads enfants se terminent? Dans une application MVC, si je fais un traitement parallèle dans mon action de contrôleur, qu'arrive-t-il aux threads enfants une fois le thread principal terminé. Seront-ils interrompus ou seront-ils terminés même après la fin du thread principal?

34
Dhawal

Parallel.ForEach() est destiné exactement à ce type de code.

D'autre part, ForAll() est destiné à être utilisé à la fin d'une requête PLINQ (éventuellement complexe).

Pour cette raison, je pense que Parallel.ForEach() est le meilleur choix ici.

Dans les deux cas, le thread actuel sera utilisé pour effectuer les calculs (ainsi que certains threads du pool de threads) et la méthode ne reviendra qu'après la fin de tout le traitement.

22
svick

Voici une explication dans MSDN:

https://docs.Microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-with-plinq#prefer-forall-to-foreach-when-it-is-possible

Sur la base de ce que j'ai lu, utilisez Parallel.ForEach() si vous voulez vous assurer que la liste est accessible séquentiellement tout en utilisant AsParallel.ForAll() ne garantit pas que les éléments de la liste sont accessibles dans l'ordre.

Pour MVC, tous les threads sont basés sur les requêtes. Le thread de l'appelant (principal) est bloqué jusqu'à ce que l'appel Parallel () soit terminé, ce qui signifie que tous les threads enfants devraient également être terminés.

Si le thread de l'appelant est abandonné, voici une explication:

http://www.albahari.com/threading/part5.aspx

PLINQ n'interrompt pas les threads de manière préventive, en raison du danger de le faire. Au lieu de cela, lors de l'annulation, il attend que chaque thread de travail se termine avec son élément actuel avant de terminer la requête. Cela signifie que toutes les méthodes externes que la requête appelle s'exécuteront jusqu'à la fin.

1
dsum