简体   繁体   中英

Isolate exceptions in await Task.WhenAll()

What is the proper way to isolate exceptions when executing Task.WhenAll(). So that when an exception is thrown in one of the processes (user), others will continue processing.

try
{
    var usersToProcess = new List<User>();

    var processes = new List<Task>();
    foreach (var user in usersToProcess)
    {
        var process = // Set up here
        processes.Add(_processHandler.Process(process));
    }

    await Task.WhenAll(processes); // await all here
}
catch (Exception ex)
{
    throw ex;
}

All the tasks will be running in parallel so even if one tasks throws exception it wont stop other tasks to stop executing. See the docs :

You apply the Task.WhenAll method to a collection of tasks. The application of WhenAll returns a single task that isn't complete until every task in the collection is completed. The tasks appear to run in parallel, but no additional threads are created. The tasks can complete in any order.

await Task.WhenAll(processes) will wait for all taks in processes to finish and then throw the first exception that was thrown by any of the tasks. So by the time you reach the catch handler, all tasks will either have completed or thrown.

You can confirm this yourself by using a counter variable:

int count = 0;
try
{
    var usersToProcess = new List<User>();

    const int n = 10;
    var processes = new List<Task>();
    for (int i = 0; i<n; ++i)
    {
        int j = i;
        processes.Add(Task.Run(() =>
        {
            Thread.Sleep(1000);
            Interlocked.Increment(ref count);

            //throw an exception in task 2 and 5
            if (j == 1 || j == 4)
                throw new Exception("...");
        }));
    }

    await Task.WhenAll(processes); // await all here
}
catch (Exception ex)
{
    Console.WriteLine(count); //will always print 10
}

Console.WriteLine(count); //will always print 10

The total number of tasks in processes will always be printed to the console in the above sample code, regardless of whether any task throws.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM