当AggregateException.InnerExceptions.Count>有任何人面临案例时1?

时间:2013-04-23 13:55:17

标签: c# .net exception-handling

我想知道,当有AggregateException.InnerExceptions.Count>时,有人遇到过案件吗? 1?

例如,TPL在AggregateException中包装了在任务正文中引发的异常。但是,当有多个内部异常时,我从未见过情况。

如何通过TPL实现这一目标?
如何使用任何 FCL(或其他广泛使用的库)类(样本将有用)来实现这一目标?

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

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

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

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抛出异常。以下内容将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()。如果您期望其他类型的例外,您可以根据需要迭代InnerException

我希望这会有所帮助。