Maison > développement back-end > C++ > Comment puis-je attendre correctement les opérations asynchrones dans une boucle parallèle.

Comment puis-je attendre correctement les opérations asynchrones dans une boucle parallèle.

Susan Sarandon
Libérer: 2025-02-01 03:21:08
original
348 Les gens l'ont consulté

How Can I Properly Await Asynchronous Operations within a Parallel.ForEach Loop in C#?

Opérations asynchrones parallèles avec Parallel.ForEach en C #

Améliorer les performances des applications implique souvent un traitement parallèle. Cependant, la combinaison d'opérations asynchrones (async / await) avec des boucles parallèles comme Parallel.ForEach présente des défis uniques. Cet article relève ces défis et fournit des solutions pour attendre correctement les tâches asynchrones dans une boucle parallèle.

Le problème: tâches asynchrones et Parallel.ForEach

Le mot-clé async dans C # permet la programmation asynchrone, renvoyant un objet Task. Le problème se pose lors de l'utilisation de méthodes async dans Parallel.ForEach parce que les fils d'arrière-plan n'attendent pas intrinsèquement les tâches asynchrones à terminer avant la fin de la boucle.

Considérez cet exemple:

<code class="language-csharp">var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
    // Pre-processing
    var response = await GetData(item);
    bag.Add(response);
    // Post-processing
});
var count = bag.Count; // count is often 0!</code>
Copier après la connexion

count Renvoie fréquemment 0 car le thread principal se déroule avant que les fils d'arrière-plan terminent leurs opérations asynchrones.

Solution: en utilisant Select et Task.WhenAll

Une solution robuste implique Select pour créer une collection d'objets Task et Task.WhenAll pour attendre que toutes les tâches se terminent:

<code class="language-csharp">var bag = new ConcurrentBag<object>();
var tasks = myCollection.Select(async item =>
{
    // Pre-processing
    var response = await GetData(item);
    bag.Add(response);
    // Post-processing
});
await Task.WhenAll(tasks);
var count = bag.Count; // count will be correct</code>
Copier après la connexion

Cette approche initie les opérations asynchrones en utilisant simultanément Select puis utilise Task.WhenAll pour garantir que toutes les tâches se terminent avant d'accéder au bag.

Solutions avancées: ForEachAsync

Pour des scénarios plus complexes, le billet de blog de Stephen Toub sur ForEachAsync fournit une solution plus sophistiquée et adaptable:

https://www.php.cn/link/33edf41c0becd0d57c35c4e27276617b

Cela offre une méthode plus contrôlée et plus efficace pour gérer les opérations asynchrones parallèles, en particulier lorsque vous traitez des exceptions potentielles ou de l'annulation. Il fournit une approche plus robuste et flexible par rapport à la méthode simple Select / Task.WhenAll.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal