假设我有以下代码:
var tasks = BuildTaskList();
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException exception)
{
}
我如何知道exception.InnerExceptions
中的哪个异常是由哪个任务引发的?
假设我有以下代码:
var tasks = BuildTaskList();
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException exception)
{
}
我如何知道exception.InnerExceptions
中的哪个异常是由哪个任务引发的?
var throwers = tasks.Where(task => task.Exception != null);
AggregateException
。据我所知。 - noseratio - open to workthrowers
是所有抛出异常的任务序列。可能是全部,可能是没有,也可能是中间任意数量 - 但它们都有自己的异常。 - Matthew Watson选项1(感谢@theodor-zoulias的评论):
您可以使用Exception.Data
属性设置任务名称:
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"]}");
}
}
选项2:
如果您不介意失去异常程序集信息的名称,您可以根据任务名称设置抛出异常的Exception.Source
(doc)属性,并在迭代时查看它:
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}");
}
}
将输出:
t1 抛出了异常
t2 抛出了异常
Exception.Source
属性旨在提供有关引发异常的程序集的信息。通过劫持此属性,您将丢失信息。对于用户定义的信息,最好使用 Exception.Data
属性。 - Theodor Zoulias 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.");
}
}
});
catch
的同一个AggregateException exception
吗? - noseratio - open to workawait WhenAll
而不是WaitAll
。 - Carlos Garcia