Interview frequency: …
Short answer
It provides a built-in way to process a collection with async code, set a precise maximum concurrency with MaxDegreeOfParallelism, and support cancellation.
Explanation
The older Parallel.ForEach supported only synchronous code and blocked threads. Parallel.ForEachAsync was designed for async/await: it processes a large array while limiting how many async operations run at once (for example, eight in parallel), and accepts a CancellationToken to cancel immediately.
Code example
await Parallel.ForEachAsync(urls, new ParallelOptions { MaxDegreeOfParallelism = 8 }, async (url, ct) => {
var content = await httpClient.GetStringAsync(url, ct);
await ProcessContentAsync(content, ct);
});Common mistakes
- Using old Parallel.ForEach with asynchronous code through async void in its delegate, so it does not wait for the operations to finish.
Follow-up questions
- How do you pass and handle CancellationToken through asynchronous call chains in ASP.NET Core?
- What is the fundamental difference between ThreadLocal<T> and AsyncLocal<T> in asynchronous .NET code?