Task.WaitAll not throwing AggregateException while one of the task is still running

1.5k views Asked by At
var moduleTimeOut = 3000;
var errorsThatOccurred = new List<string>();
List<string> names = new List<string>() { "Task1", "Task2", "Task3" };

var tasks = new List<Task<string>>();
names.ForEach( name => tasks.Add( Task<string>.Factory.StartNew((m) => MyTask(m.ToString()), name)));

try
{
    var allTasksCompletedInTime = Task.WaitAll(tasks.ToArray(), moduleTimeOut);

}
catch (AggregateException ex)
{
    foreach (var exception in ex)
    {
        errorsThatOccurred.Add(exception.ToString());
    }
}
private string MyTask(string name)
{
    if (name.Equals("Task1"))
        System.Threading.Thread.Sleep(5000);

    if (name.Equals("Task2"))
        throw new ArgumentException("Task2 has thrown an exception");

    return "MyTask has finished the execution. Task is " + name;
}

I am having some problem capturing AggregateException. Here are my different scenarios.

  1. All tasks are completed in time. → Works fine.

  2. Task2 throws an error and all other tasks finished in time. → Caught AggregateException and can see ArgumentException thrown by Task2.

  3. Task1 didn't finish in time and still running. Task2 throws an error. Task3 is completed. → AggregateException didn't fire. I see the Task2 status is faulted and exception information in Exception property.

I don't know why it is not throwing AggregateException in scenario #3. Any help?

1

There are 1 answers

2
Matt Smith On

That's the expected behavior. If you hit the timeout before all the tasks have completed (either ran to completion, faulted, or cancelled), it will not throw the exception: it will just return false.

It will only throw the exception in the case where all tasks have completed within the allotted time.