SoFunction
Updated on 2025-03-09

Summary of the explanation and usage of WhenAll in .Net

In .NET, WhenAll is an extension method related to asynchronous programming, which belongs to the TaskExtensions class under the namespace. This method is mainly used to process a set of Task objects and wait for them to complete. When all tasks are completed, WhenAll returns a Task<Task[]> object containing all tasks results.

explain

The WhenAll method is used to execute multiple asynchronous tasks in parallel and wait for them to complete. This helps simplify the asynchronous programming model, especially when you have multiple independent tasks that need to be executed in parallel and you want to wait until they are all completed before continuing to execute subsequent code.

usage

Here is a one that uses WhenAllSimple example

using System;
using ;
class Program
{
    static async Task Main(string[] args)
    {
        // Create three asynchronous tasks        Task task1 = (() =&gt; DoSomethingAsync("Task 1"));
        Task task2 = (() =&gt; DoSomethingAsync("Task 2"));
        Task task3 = (() =&gt; DoSomethingAsync("Task 3"));
        // Use WhenAll to wait for all tasks to complete        Task[] tasks = { task1, task2, task3 };
        await (tasks);
        ("All tasks are completed.");
    }
    static async Task DoSomethingAsync(string taskName)
    {
        ($"Starting {taskName}...");
        await (1000); // Simulation time-consuming operation        ($"Completed {taskName}.");
    }
}

In the example above, we create three asynchronous tasks task1, task2, and task3, each calling the DoSomethingAsync method to simulate some asynchronous operations. Then we use (tasks) to wait for all tasks to complete. When all tasks are completed, the program will output "All tasks are completed."

Note that WhenAll will not return any task results. If you need to access the results of each task, you can use an overloaded version of , which returns a Task<TResult[]> object, where TResult is the type of the task's return value. For example, if each task returns an int value, a Task<int[]> object will be returned.

Things to note

WhenAll will not cancel any tasks. If you need to cancel a set of tasks, you need to handle the cancel logic of each task separately.
If one of the tasks throws an exception, WhenAll waits for all other tasks to complete, and then throws an AggregateException containing the exceptions for all tasks. This means that even if a task fails, WhenAll continues to wait for other tasks to complete.
WhenAll returns a task that you can use the await keyword to wait for it to complete. During the waiting period, the calling thread is not blocked, which helps improve application responsiveness and performance.

Extension: Use and Difference between WaitAll and WhenAll

Students who have used .net asynchronous programming know that it is really much more convenient to implement than before multi-threaded programming. Today, I will review and summarize the two programming methods of WaitAll and WhenAll (of course, WaitAny and WhenAny have the same operation)

1:WaitAll

In my opinion, this method is mainly to solve the problem of synchronous execution of multiple less relevant operations, which takes a lot of time. This method can enable them to execute asynchronously and simultaneously. Then, after all operations are completed, the next operation will be performed. Talk is cheap, show you code!

For example:

var response1 = new PriceDataResponse();
                var response2 = new PriceDataResponse();
                //Define two asynchronous tasks task1 and task2                Task task1 = (() =&gt;
                {
                    response1 = SampleFunc(1);
                });
                Task task2 = (() =&gt;
                {
                        response2 =  SampleFunc(2);
                });
                //Waiting for the execution of two tasks to be completed (execute simultaneously)                (task1, task2);
                //After execution, perform the following operations                if (())
                {
                    return response1;
                }
                if (())
                {
                    return response2;
                }

In other words, the two tasks, task1 and task2, are running non-stop in the child thread after they are defined. It is a waiting process. The parameters are the Task parameters. Once all execution is completed, they will continue to be executed. This is blocking, which is relatively easy to understand.

In this way, WaitAny will be easy to understand. If any Task in the parameter is executed, the subsequent logic will be executed.

2:WhenAll

WhenAll is actually the same as WaitAll to achieve the same function, but another layer of packaging is made on WaitAll, and you can understand it by looking at the code.

var response1 = new PriceDataResponse();
                var response2 = new PriceDataResponse();
                //Define two asynchronous tasks task1 and task2                Task task1 = (() =&gt;
                {
                    response1 = SampleFunc(1);
                });
                Task task2 = (() =&gt;
                {
                    response2 = SampleFunc(2);
                });
                //Waiting for the execution of two tasks to be completed (execute simultaneously)                (task1, task2).ContinueWith(p =&gt;
                {
                    if (())
                    {
                        return response1;
                    }
                    if (())
                    {
                        return response2;
                    }
                    return null;
                }, );

Functionally the same as WaitAll, which means that after the two asynchronous ends, continue to do the processing in ContinueWith. The p here is equivalent to a Task. If the Task defined above has a return value, then it can be used to get the value here.

WhenAny is the same. If any one is completed, execute the following code.

This is the end of this article about the explanation and usage of WhenAll in .Net. For more related content on usage of WhenAll, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!