You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确捕获async异步方法内部抛出的异常?

问题原因
  • 原代码中Task.Run(async () => await DoTask())仅提交了后台异步任务,没有等待任务执行完成,try块在任务抛出异常前就已经执行结束,异常无法被当前catch捕获。未被观察的Task异常默认会被运行时忽略。
解决方案

方案1:使用异步Main方法(推荐,C# 7.1及以上版本支持)

直接await任务执行,异常会被正常抛出到await位置:

private static async Task DoTask()
{
    await Task.Delay(10000);
    throw new Exception("Exception!");
}

public static async Task Main(string[] args)
{
    try
    {
        // 不需要额外包装Task.Run的场景可以直接写 await DoTask()
        await Task.Run(async () => await DoTask());
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    Console.WriteLine("End");
    Console.ReadKey();
}

方案2:同步阻塞等待(兼容旧版C#)

如果不能使用异步Main,可以调用GetAwaiter().GetResult()或者Wait()等待任务完成:

public static void Main(string[] args)
{
    try
    {
        // GetAwaiter().GetResult()会直接抛出原始异常,不会包装为AggregateException
        Task.Run(async () => await DoTask()).GetAwaiter().GetResult();
        
        // 如果用Wait()需要捕获AggregateException解包:
        // Task.Run(async () => await DoTask()).Wait();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    // 使用Wait()的场景需要替换catch为:
    // catch (AggregateException ae)
    // {
    //     foreach (var innerEx in ae.InnerExceptions)
    //     {
    //         Console.WriteLine(innerEx.Message);
    //     }
    // }

    Console.WriteLine("End");
    Console.ReadKey();
}

内容的提问来源于stack exchange,提问作者user788454

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:06:05