Reputation: 53
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.
Upvotes: 4
Views: 2515
Reputation: 10042
You can make it more cleat with AsyncEnumerator NuGet Package:
using System.Collections.Async;
await messagesByFromNumber.ParallelForEachAsync(async messageGroup =>
{
foreach (var message in messageGroup)
{
await message.SendAsync();
}
}, maxDegreeOfParallelism: 10);
Upvotes: 0
Reputation: 116548
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)
Upvotes: 5