问题 为什么unawaited异步方法不会抛出异常?


我认为异步方法应该像普通方法一样,直到他们到达等待。

为什么这不会抛出异常?

有没有办法在没有等待的情况下抛出异常?

using System;
using System.Threading.Tasks;

public class Test
{
    public static void Main()
    {
        var t = new Test();
        t.Helper();
    }

    public async Task Helper()
    {
        throw new Exception();
    }
}

937
2018-06-26 23:25


起源

作为历史记录,例外最初是按照您的预期“直接”提出的。但是,这种行为令人困惑,因为之前和之后的异常 await 会有不同的表现,而且可能会有所不同 真 令人困惑的是 await 有条件的。 - Stephen Cleary
@StephenCleary什么时候改变了?在CTP阶段? - i3arnon
@ I3arnon:是的; IIRC只有第一个CTP表现出这种方式。 - Stephen Cleary
@Craig,另一种选择是使用 async void,检查 “火与忘法”。 - Noseratio


答案:


内部抛出的异常 async 通过设计,方法存储在返回的任务中。要获得例外,您可以:

  1. await 任务: await t.Helper();
  2. Wait 任务: t.Helper().Wait();
  3. 检查任务 Exception 属性  任务已完成: var task = t.Helper(); Log(task.Exception);
  4. 为处理异常的任务添加延续: t.Helper().ContinueWith(t => Log(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

你最好的选择是第一个。只是 await 任务和处理异常(除非有特殊原因你不能这样做)。更多 .NET 4.5中的任务异常处理


15
2018-06-26 23:33