With the upcoming release of .NET 9, developers are getting a handy new tool to handle asynchronous tasks more efficiently: Task.WhenEach. This method allows you to process tasks as they complete, rather than waiting for all tasks to finish. This can be particularly useful in scenarios where tasks have varying completion times and you want to act on each one as soon as it’s done.

The Problem with Task.WhenAll and Task.WhenAny

In previous versions of .NET, handling multiple asynchronous tasks required using methods like Task.WhenAll or Task.WhenAny. However, both have their limitations:

  • Task.WhenAll waits for all tasks to complete before proceeding, which isn’t ideal if you want to process each task result as soon as it’s available.
  • Task.WhenAny returns the first completed task but ignores the others, requiring additional logic to track and handle the remaining tasks.

Introducing Task.WhenEach

Task.WhenEach addresses these issues by providing an IAsyncEnumerable<Task> that yields each task as it completes. This allows you to use an await foreach loop to process tasks one by one as they finish, simplifying your code and improving efficiency.

Here’s an example of how you can use Task.WhenEach:

var tasks = new List<Task<string>>(5);

for (var i = 0; i < 5; i++)
{
    tasks.Add(GetRandomStringAsync());
}

await foreach (var text in Task.WhenEach(tasks))
{
    Console.WriteLine(await text);
}

async Task<string> GetRandomStringAsync()
{
    var delay = Random.Shared.Next(1000, 10000);
    await Task.Delay(delay);
    return Guid.NewGuid().ToString();
}

How It Works

  1. Creating Tasks: We create a list of tasks that simulate asynchronous operations with varying completion times.
  2. Using Task.WhenEach: The Task.WhenEach method is called with our list of tasks. It returns an IAsyncEnumerable<Task>, which we can iterate over using await foreach.
  3. Processing Results: As each task completes, we await its result and print it to the console.

This approach ensures that you process each task result as soon as it’s available, without waiting for all tasks to complete.

Benefits

  • Efficiency: Start processing results immediately as each task completes.
  • Simplicity: Cleaner and more readable code compared to manually tracking completed tasks.
  • Scalability: Easily handles a large number of tasks with varying completion times.

Conclusion

Task.WhenEach provides a more efficient and straightforward way to process tasks as they complete, addressing the limitations of Task.WhenAll and Task.WhenAny. This new method enhances the responsiveness and performance of your applications by allowing immediate processing of completed tasks. Let’s see what else the new release brings us.

Affiliate promo

If you love learning new stuff and want to support me, consider buying a course from Dometrain using this link: Browse courses – Dometrain. Thank you!

Leave a comment

Trending