0
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?

user1186065
  • 1,847
  • 3
  • 17
  • 22

1 Answers1

3

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.

Matt Smith
  • 17,026
  • 7
  • 53
  • 103
  • Thanks! Then how should I capture all exceptions in this case? I can't wait for all the tasks to be completed to capture all the exceptions. – user1186065 Aug 22 '13 at 17:24
  • @user1186065 You'll need to look at the state of each of the tasks you passed to `WaitAll`, and keep track of those that are faulted. Or you could create your own version of `WaitAll` that has your desired behavior that you use instead. – Servy Aug 22 '13 at 17:41