C# - 抛出异常但调用方法已经完成的任务会发生什么?

sha*_*y__ 2 .net c# task-parallel-library async-await

如果if满足以下语句将会发生什么(以及为什么)并Bar()抛出异常?

    async Task Foo()
    {
        Task<object> myTask = Bar();
        if (condition)
        {
            return;
        }
        else
        {
            await myTask;
            // ....
            return;
        }
    }
Run Code Online (Sandbox Code Playgroud)

异常会被抓住吗?由谁?

Ser*_*rvy 5

不,这个例外不会被抓住.你需要专门添加一个延续Task(注意,当你await在任务中添加一个延续时).


Lua*_*aan 5

如果Bar抛出异常,它将在您调用它的地方被抛出。

但是,如果TaskBar回报包装异常,会发生什么取决于你的.NET运行时版本-为.NET 4.0,它将带给了你的整个过程,因为它最终会导致要在终结器线程抛出的异常(或线程池线程)。对于 .NET 4.5+,异常将被静默处理。

无论如何,你也不想要。您应该始终明确处理可以在异步任务中传播的任何异步异常。如果您不想await在代码的某个分支中执行任务(例如,您正在预加载您认为需要但不需要的数据),至少在任务上绑定一个延续以处理任何可能的优雅地例外。