Reputation: 101166
Let's say that I got the following code:
var tasks = BuildTaskList();
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException exception)
{
}
How do I know which task threw which of the exceptions in exception.InnerExceptions
?
Upvotes: 7
Views: 7315
Reputation: 8762
Option1 (credit to @theodor-zoulias comment):
You can set the Exception.Data
property with the task name:
var task1 = Task.Factory.StartNew(() =>
{
try
{
throw new Exception();
}
catch (Exception exception)
{
exception.Data["task"] = "task1";
throw exception;
}
});
var task2 = Task.Factory.StartNew(() =>
{
try
{
throw new Exception();
}
catch (Exception exception)
{
exception.Data["task"] = "task2";
throw exception;
}
});
try
{
Task.WaitAll(task1, task2);
}
catch (AggregateException ae)
{
foreach (var exception in ae.InnerExceptions)
{
Console.WriteLine($"Exception was thrown by {exception.Data["task"]}");
}
}
Option2:
If you don't mind loosing the name of the exception's assembly information, You can set the Exception.Source
(doc) property of the thrown exception based on the task name and look at it while iterating:
var t1 = Task.Factory.StartNew(() =>
{
throw new Exception() { Source = "t1" };
});
var t2 = Task.Factory.StartNew(() =>
{
throw new Exception() { Source = "t2" };
});
try
{
Task.WaitAll(t1, t2);
}
catch (AggregateException ae)
{
foreach (var exception in ae.InnerExceptions)
{
Console.WriteLine($"Exception was thrown by {exception.Source}");
}
}
Will output:
Exception was thrown by t1
Exception was thrown by t2
Upvotes: 0
Reputation: 37780
var t1 = Task.Factory.StartNew(() => Console.WriteLine("Task 1"));
var t2 = Task.Factory.StartNew(() => Console.WriteLine("Task 2"));
var t3 = Task.Factory.StartNew(() => { throw new InvalidOperationException(); });
var t4 = Task.Factory.StartNew(() => Console.WriteLine("Task 4"));
Task.Factory.ContinueWhenAll(new[] { t1, t2, t3, t4 }, tasks =>
{
foreach (var t in tasks)
{
if (t.Status == TaskStatus.Faulted)
{
// this will run for t3
Console.WriteLine("This task has been faulted.");
}
}
});
Upvotes: 0
Reputation: 109762
var throwers = tasks.Where(task => task.Exception != null);
Upvotes: 2
Reputation: 17444
You still have the list of Tasks
, and each Task
has an Exception
property. Using that you can figure out which exceptions belong with which Task
.
But, if you can, it'd be better to use Task.WhenAll
or TaskFactory.ContinueWhenAll
than do a blocking Wait.
Upvotes: 9