6

假设我得到以下代码:

var tasks = BuildTaskList();
try
{
    Task.WaitAll(tasks.ToArray());
}
catch (AggregateException exception)
{

}

我怎么知道哪个任务抛出了哪个异常exception.InnerExceptions

4

4 回答 4

9

您仍然有 的列表Tasks,并且每个Task都有一个Exception属性。使用它,您可以找出哪些异常属于哪个Task.

但是,如果可以的话,最好使用Task.WhenAllTaskFactory.ContinueWhenAll执行阻塞等待。

于 2013-08-19T12:51:07.063 回答
2
var throwers = tasks.Where(task => task.Exception != null);
于 2013-08-19T12:52:35.663 回答
0
        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.");
                    }
                }
            });
于 2013-08-19T12:57:40.957 回答
0

选项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 抛出异常

于 2020-03-20T07:54:40.183 回答