Skip to main content
3 of 4
Corrected that Parallel.ForEach does wait for its actions to complete, but acts like most other code that does not await async action.

Parallel.ForEach blocks the calling thread until the specified actions complete. However, it does not automatically await async method calls, similar to how normally calling an async method without awaiting it would continue without waiting for the async method to complete.

An example of Parallel.ForEach not automatically awaiting an async method call:

using System; using System.Linq; using System.Threading.Tasks; namespace ParrellelEachExample { class Program { static void Main(string[] args) { var indexes = new int[] { 1, 2, 3 }; RunExample((prefix) => Parallel.ForEach(indexes, (i) => DoSomethingAsync(i, prefix)), "Parallel.Foreach"); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("*You'll notice the tasks haven't run yet, because the main thread was not blocked*"); Console.WriteLine("Press any key to start the next example..."); Console.ReadKey(); RunExample((prefix) => Task.WhenAll(indexes.Select(i => DoSomethingAsync(i, prefix)).ToArray()).Wait(), "Task.WhenAll"); Console.WriteLine("All tasks are done. Press any key to close..."); Console.ReadKey(); } static void RunExample(Action<string> action, string prefix) { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($"{Environment.NewLine}Starting '{prefix}'..."); action(prefix); Console.WriteLine($"{Environment.NewLine}Finished '{prefix}'{Environment.NewLine}"); } static async Task DoSomethingAsync(int i, string prefix) { await Task.Delay(i * 1000); Console.WriteLine($"Finished: {prefix}[{i}]"); } } } 

Here is the result:

enter image description here

Conclusion:

Parallel.ForEach does not automatically await async actions. If you need to wait for async actions to complete, make sure to await them.

Rogala
  • 2.8k
  • 28
  • 27