Comment structurer le code ci-dessous pour que la méthode async soit invoquée?
Parallel.For(0, elevations.Count(), delegate(int i)
{
allSheets.AddRange(await BuildSheetsAsync(userID, elevations[i], includeLabels));
});
Parallel.For()
ne fonctionne pas bien avec les méthodes async
. Si vous n'avez pas besoin de limiter le degré de parallélisme (c'est-à-dire que vous êtes d'accord avec toutes les tâches s'exécutant en même temps), vous pouvez simplement démarrer toutes les Task
s et attendre qu'elles se terminent:
var tasks = Enumerable.Range(0, elevations.Count())
.Select(i => BuildSheetsAsync(userID, elevations[i], includeLabels));
List<Bitmap> allSheets = (await Task.WhenAll(tasks)).SelectMany(x => x).ToList();
Je vous recommande de jeter un œil à cette question que j'ai posée il y a quelques jours et qui a fini par me répondre, je cherchais essentiellement une méthode ForEach parallèle et asynchrone .
La méthode utilise SemaphoreSlim
pour traiter les choses en parallèle et elle accepte les méthodes asynchrones comme action d'entrée.
Vous voudrez peut-être également jeter un coup d'œil aux deux liens que j'ai fournis à la fin de ma réponse, ils ont été vraiment utiles pour réaliser un tel comportement et ils contiennent également une autre façon de le faire en utilisant un Partitioner
à la place.
Personnellement, je n'ai pas aimé le Parallel.For
parce que c'est un appel synchrone comme expliqué dans les liens que j'ai donnés; Je voulais tout 'async' :-)
Le voici: Téléchargement asynchrone et parallèle de fichiers
Vous pouvez essayer ce code que j'utilise. il en utilisant foreach et SemaphoreSlim pour obtenir parallèle asynchrone.
public static class ParallelAsync
{
public static async Task ForeachAsync<T>(IEnumerable<T> source, int maxParallelCount, Func<T, Task> action)
{
using (SemaphoreSlim completeSemphoreSlim = new SemaphoreSlim(1))
using (SemaphoreSlim taskCountLimitsemaphoreSlim = new SemaphoreSlim(maxParallelCount))
{
await completeSemphoreSlim.WaitAsync();
int runningtaskCount = source.Count();
foreach (var item in source)
{
await taskCountLimitsemaphoreSlim.WaitAsync();
Task.Run(async () =>
{
try
{
await action(item).ContinueWith(task =>
{
Interlocked.Decrement(ref runningtaskCount);
if (runningtaskCount == 0)
{
completeSemphoreSlim.Release();
}
});
}
finally
{
taskCountLimitsemaphoreSlim.Release();
}
}).GetHashCode();
}
await completeSemphoreSlim.WaitAsync();
}
}
}
usage:
string[] a = new string[] {
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20"
};
Random random = new Random();
await ParallelAsync.ForeachAsync(a, 2, async item =>
{
Console.WriteLine(item + " start");
await Task.Delay(random.Next(1500, 3000));
Console.WriteLine(item + " end");
});
Console.WriteLine("All finished");
toute suggestion s'il vous plaît faites le moi savoir.