I was reading this post about Parallel.ForEach where it was stated that "Parallel.ForEach is not compatible with passing in a async method."
So, to check I write this code:
static async Task Main(string[] args)
{
var results = new ConcurrentDictionary<string, int>();
Parallel.ForEach(Enumerable.Range(0, 100), async index =>
{
var res = await DoAsyncJob(index);
results.TryAdd(index.ToString(), res);
});
Console.ReadLine();
}
static async Task<int> DoAsyncJob(int i)
{
Thread.Sleep(100);
return await Task.FromResult(i * 10);
}
This code fills in the results dictionary concurrently.
By the way, I created a dictionary of type ConcurrentDictionary<string, int> because in case I have ConcurrentDictionary<int, int> when I explore its elements in debug mode I see that elements are sorted by the key and I thought that elenents was added consequently.
So, I want to know is my code is valid? If it "is not compatible with passing in a async method" why it works well?
Parallel.ForEachis made for CPU-intensive computations and doesn't recognize async methods. It doesn't await them, essentially converting them toasync voidfire-and-forget calls. Your method isn't async anyway, so it's not possible to say what the correct call would look likeI want to know is my code is valid?No.why it works well?It doesn't but you don't realize it because a) it doesn't perform any async work.Parallel.ForEach- "Arrange for a number of threads to perform the following work in parallel" -async- "Well, there's no useful work for this thread to do until something else completes this awaitable". Even if it did work (it doesn't, it's entirely synchronous as Panagitotis says), you're combining things in an odd way that overallocates resources and then ignores them.awaitany async calls.asyncdoesn't await anything, nor does it make anything run asynchronously.async voidcalls can't be awaited, that's why they are considered bugs outside event handlers.