8

我想知道,有没有人遇到过病例,当AggregateException.InnerExceptions.Count> 1?

例如,TPL 将在任务主体中引发的异常包装在AggregateException. 但我从未见过有不止一个内在例外的情况。

如何使用 TPL 实现这一点?
如何使用任何FCL(或另一个广泛使用的库)类来实现这一点(示例将很有用)?

我知道,有可能建立这样的实例AggregateException,但问题是关于实践。我问这个,因为我想了解,什么是最好的处理方式AggregateException

4

2 回答 2

8

典型的情况是一个任务依赖于多个任务,并且其中多个任务引发异常。例如:

var t1 = Task.Factory.StartNew( () => { throw new Exception(); } );
var t2 = Task.Factory.StartNew( () => Console.WriteLine("Innocuous") );
var t3 = Task.Factory.StartNew( () => { throw new Exception(); } );

// Output: 2
var t4 = Task.WhenAll(t1, t2, t3)
             .ContinueWith(t => Console.WriteLine(t.Exception.InnerExceptions.Count), 
                           TaskContinuationOptions.OnlyOnFaulted);
于 2013-04-23T14:01:14.917 回答
1

正如 Ani 所说,这些AggregateExceptions可以通过多个连续Task的 s 使用延续来观察异常来创建。

Task t1 = Task.Factory.StartNew(() => { throw new Exception(); });
Task t2 = Task.Factory.StartNew(() => { throw new Exception(); });
Task t3 = Task.WhenAll(t1, t2)
    .ContinueWith(t => t.Exception.InnerExceptions.Count(), 
    TaskContinuationOptions.OnlyOnFaulted);

通常你会AggregateException在一个延续中处理。Task延续可以通过前面任务的异常属性来查明前面是否抛出了异常。以下将 a 的结果打印NullReferenceException到控制台

Task task1 = Task.Factory.StartNew (() => { throw null; });
Task task2 = task1.ContinueWith (ant => Console.Write(ant.Exception());

如果task1抛出异常并且该异常未被继续捕获/查询,则它被视为未处理并且应用程序终止。Status使用延续,通过关键字确定任务的结果就足够了

asyncTask.ContinueWith(task =>
{
    // Check task status.
    switch (task.Status)
    {
        // Handle any exceptions to prevent UnobservedTaskException.             
        case TaskStatus.RanToCompletion:
            if (asyncTask.Result)
            {
                // Do stuff...
            }
            break;
        case TaskStatus.Faulted:
            if (task.Exception != null)
                mainForm.progressRightLabelText = task.Exception.Flatten().Message;
            else
                mainForm.progressRightLabelText = "Operation failed!";
        default:
            break;
    }
}

在上面我只期望一个例外 - 以确保这是我可以调用的情况Flatten()。如果您期望其他类型的异常,您可以根据需要遍历InnerExceptions。

我希望这有帮助。

于 2013-04-23T14:13:51.860 回答