How to better understand the code/statements from “Async - Handling multiple Exceptions” article?

不羁岁月 提交于 2019-11-29 08:24:58

The article is wrong. When you run your code, the awaited Task contains an exception that looks something like this:

AggregateException
  AggregateException
    NullReferenceException
  AggregateException
    ArgumentException

What await (or, more specifically, TaskAwaiter.GetResult()) does here is that it takes the outer AggregateException and rethrows its first child exception. Here, that's another AggregateException, so that's what is thrown.

Example of code where a Task has multiple exceptions and one of them is directly rethrown after await would be to use Task.WhenAll() instead of AttachedToParent:

try
{
    await Task.WhenAll(
        Task.Factory.StartNew(() => { throw new NullReferenceException(); }),
        Task.Factory.StartNew(() => { throw new ArgumentException(); }));
}
catch (AggregateException ex)
{
    // this catch will never be target
    Console.WriteLine("** {0} **", ex.GetType().Name);
}
catch (Exception ex)
{
    Console.WriteLine("## {0} ##", ex.GetType().Name);
}

In response to your "Update 2", the reasoning is still the same as in svick's answer. The task contains an AggregateException, but awaiting it throws the first InnerException.

The additional information you need is in the Task.WhenAll documentation (emphasis mine):

If any of the supplied tasks completes in a faulted state, the returned task will also complete in a Faulted state, where its exceptions will contain the aggregation of the set of unwrapped exceptions from each of the supplied tasks.

So that Task's exceptions will look like:

AggregateException 
    NullReferenceException 
    ArgumentException
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!