As I and others mentioned in comments Parallel.ForEach
does not support async functions the reason is when you did async (entry) => ...
that is the same as
Parallel.ForEach(entries, Example);
//elsewhere
async void Example(Entry entry)
{
...
}
Because the function is async void
the ForEach
can't tell when a function is "done" so it will just think it is done when you hit the first await
instead of when the task finishes.
The way to fix this is to use a library that can suport async functions, TPL Dataflow is a good one. You get it by installing the NuGet package to your project Microsoft.Tpl.Dataflow
. You could recreate your previous code as
private const int MAX_PARALLELISM = 15
public async Task ProcessEntries(IEnumerable<Entry> entries)
{
var block = new ActionBlock<Entry>(async (entry) =>
{
//This is now a "async Task" instead of a async void
},
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = MAX_PARALLELISM
});
foreach(var entry in entries)
{
await block.SendAsync(entry);
}
block.Complete();
await block.Completion;
DoExtraWorkWhenDone();
}