using System.Threading.Tasks;
public static class Program
public static void Main()
var task1 = Task.FromResult(13);
var task2 = Task.FromCanceled<int>(new CancellationToken(true));
var task3 = Task.FromCanceled<int>(new CancellationToken(true));
var task4 = Task.FromException<int>(new ApplicationException());
var task5 = Task.FromException<int>(new OverflowException());
Test("Successful+Canceled+Canceled", new[] { task1, task2, task3 });
Test("Successful+Failed+Failed", new[] { task1, task4, task5 });
Test("Successful+Canceled+Failed+Failed", new[] { task1, task2, task4, task5 });
Test("Successful+Canceled+Canceled+Failed", new[] { task1, task2, task3, task4 });
static void Test(string title, Task<int>[] tasks)
Console.WriteLine(title);
try { Task.WaitAll(tasks); }
catch (AggregateException ex)
Console.WriteLine($"WaitAll(): {ToString(ex)}");
try { Task.WhenAll(tasks).Wait(); }
catch (AggregateException ex)
Console.WriteLine($"WhenAll.Wait(): {ToString(ex)}");
static string ToString(AggregateException aex) {
return $"({aex.InnerExceptions.Count}) " + String.Join(", ", aex.InnerExceptions.Select(ex => ex.GetType().Name));