J'aimerais gérer une collection en parallèle, mais j'ai du mal à l'implémenter et j'espère donc avoir de l'aide.
Le problème survient si je veux appeler une méthode marquée async en C #, dans le lambda de la boucle parallèle. Par exemple:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
// some pre stuff
var response = await GetData(item);
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Le problème se produit lorsque le nombre est égal à 0, car tous les threads créés ne sont en fait que des threads d'arrière-plan et l' Parallel.ForEach
appel n'attend pas la fin. Si je supprime le mot-clé async, la méthode ressemble à ceci:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, item =>
{
// some pre stuff
var responseTask = await GetData(item);
responseTask.Wait();
var response = responseTask.Result;
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Cela fonctionne, mais cela désactive complètement l'intelligence d'attente et je dois faire un peu de gestion manuelle des exceptions. (Supprimé par souci de concision).
Comment puis-je implémenter une Parallel.ForEach
boucle, qui utilise le mot clé await dans le lambda? C'est possible?
Le prototype de la méthode Parallel.ForEach prend un Action<T>
paramètre as, mais je veux qu'il attende mon lambda asynchrone.
await
deawait GetData(item)
votre deuxième bloc de code car cela produirait une erreur de compilation en l'état.Réponses:
Si vous voulez juste un parallélisme simple, vous pouvez le faire:
Si vous avez besoin quelque chose de plus complexe, consultez Stephen Toub
ForEachAsync
poste .la source
dop
tâches et chacune d'elles traite ensuite un sous-ensemble de la collection d'entrée en série.Task.Run
sans obtenirawait
le résultat, cela ne fait que lancer un travail d'incendie et d'oubli sur le pool de threads. C'est presque toujours une erreur.Vous pouvez utiliser la
ParallelForEachAsync
méthode d'extension du package NuGet AsyncEnumerator :la source
maxDegreeOfParallelism
>maxDegreeOfParalellism
Avec
SemaphoreSlim
vous pouvez obtenir un contrôle de parallélisme.la source
Mon implémentation légère de ParallelForEach async.
Fonctionnalités:
Exemple d'utilisation:
la source
J'ai créé une méthode d'extension pour cela qui utilise SemaphoreSlim et permet également de définir un degré maximal de parallélisme
Exemple d'utilisation:
la source