Jeff Glazier Jeff Glazier - 3 months ago 42
C# Question

Parallel execution of a loop that uses async

I'm writing a Windows service and am looking for a way to execute a number of foreach loops in parallel, where each loop makes a call to an asynchronous (TAP) method. I initially tried the following code, which doesn't work because Parallel.ForEach and async/await are not compatible. Does anyone know whether there is an alternate approach that can achieve this?

Parallel.ForEach(messagesByFromNumber, async messageGroup =>
{
foreach (var message in messageGroup)
{
await message.SendAsync();
}
});


For the sake of clarity, due to the way that SendAsync() operates, each copy of the foreach loop must execute serially; in other words, the foreach loop cannot become concurrent / parallel.

Answer

There's no need to use Parallel.Foreach if your goal is to run these concurrently. Simply go over all your groups, create a task for each group that does a foreach of SendAsync, get all the tasks, and await them all at once with Task.WhenAll:

var tasks = messagesByFromNumber.Select(async messageGroup =>
{
    foreach (var message in messageGroup)
    {
        await message.SendAsync();
    }
});
await Task.WhenAll(tasks)
Comments