Throw Exception inside a Task - “await” vs Wait()

2019-02-11 15:50发布

问题:

static async void Main(string[] args)
{
    Task t = new Task(() => { throw new Exception(); });

    try
    {                
        t.Start();
        t.Wait();                
    }
    catch (AggregateException e)
    {
        // When waiting on the task, an AggregateException is thrown.
    }

    try
    {                
        t.Start();
        await t;
    }
    catch (Exception e)
    {
        // When awating on the task, the exception itself is thrown.  
        // in this case a regular Exception.
    }           
}

In TPL, When throwing an exception inside a Task, it's wrapped with an AggregateException.
But the same is not happening when using the await keyword.
What is the explanation for that behavior ?

回答1:

The goal is to make it look/act like the synchronous version. Jon Skeet does a great job explaining this in his Eduasync series, specifically this post:

http://codeblog.jonskeet.uk/2011/06/22/eduasync-part-11-more-sophisticated-but-lossy-exception-handling/



回答2:

In TPL AggregateException is used because you can have multiple tasks in wait opration(task can have child tasks attached), so many of them can throw exceptions. Look at Exceptions in child tasks section

https://msdn.microsoft.com/ru-ru/library/dd997417(v=vs.110).aspx

In awaityou always have just one task

See also https://msdn.microsoft.com/ru-ru/library/dd997415(v=vs.110).aspx