首页 > 解决方案 > C#:在没有 [await] 的情况下调用 [async] 方法不会捕获其抛出的异常?

问题描述

我有这个代码片段:

class Program
{
    public static async Task ProcessAsync(string s)
    {
        Console.WriteLine("call function");
        if (s == null)
        {
            Console.WriteLine("throw");
            throw new ArgumentNullException("s");
        }
        Console.WriteLine("print");
        await Task.Run(() => Console.WriteLine(s));
        Console.WriteLine("end");
    }
    public static void Main(string[] args)
    {
        try
        {
            ProcessAsync(null);
        }
        catch(Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

它运行并打印:

call function
throw

好的,抛出了异常,但是主函数的try/catch无法捕获异常,如果我删除try/catch,main也不会报告未处理的异常。这很奇怪,我用谷歌搜索,它说 [await] 中有陷阱,但没有解释如何以及为什么。

所以我的问题是,为什么这里的异常没有被捕获,使用等待的陷阱是什么?

非常感谢。

标签: c#asynchronousexceptionasync-awaitthrow

解决方案


async方法中,任何异常都会被运行时捕获并放在返回的Task. 如果您的代码忽略了方法Task返回的async值,那么它将不会观察到这些异常。大多数任务应该await在某个时候被编辑以观察它们的结果(包括异常)。

最简单的解决方案是使您的Main异步:

public static async Task Main(string[] args)
{
  try
  {
    await ProcessAsync(null);
  }
  catch(Exception e)
  {
    Console.WriteLine(e.Message);
  }
}

推荐阅读