异常永远不会到达异步方法中的处理程序(C#)[重复]

Posted

技术标签:

【中文标题】异常永远不会到达异步方法中的处理程序(C#)[重复]【英文标题】:Exception never reaching the handler in async method (C#) [duplicate] 【发布时间】:2013-07-29 11:48:01 【问题描述】:

我有一个简单的结构,我很难理解它为什么起作用(或不起作用)我认为它应该如何起作用。

基本上有两种方法

private async void DoStuff()

    try 
        AuthenticationStuff();
    catch(UnauthorizedAccessException)
        UI.Display("AMAGAD!");
    


private async void AuthenticationStuff()

    var user = GetUser();
    if(user == null) throw new UnauthorizedAccessException();

    DoMoreAuthenticationStuff();

现在的问题是异常永远不会到达DoStuff() 方法的处理程序。我的第一直觉是“嘿,这是一个异步方法,我必须等待它”,但我也不能这样做,因为显然 async void 与 async Task<void> 不同。

我试图了解这里发生了什么。为什么异常没有进入处理程序,而是调试器在 "DoMoreAuthenticationStuff()" 处中断并出现未处理的异常错误?

【问题讨论】:

【参考方案1】:

async void 方法引发的异常直接转到该方法启动时处于活动状态的SynchronizationContext。这是您应该避免使用async void 的原因之一。我在我的 MSDN 文章 Best Practices in Asynchronous Programming 中介绍了这个和其他原因。

要捕获此类异常,请将您的 async void 方法更改为 async Taskawait 返回的任务。

【讨论】:

谢谢你,斯蒂芬!这正是我一直在寻找的。而且你那篇文章很有见地!【参考方案2】:

我的第一直觉是“嘿,这是一个异步方法,我必须等待 它”,但我也不能这样做,因为显然 async void 是不同的 来自异步任务。

你可以直接说async Task MyMethod()。然后你可以等待它的结果来传播异常(并等待完成)。

另请参阅 Stephen Cleary 的回答以了解更多详情。

【讨论】:

以上是关于异常永远不会到达异步方法中的处理程序(C#)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

捕获调用异步方法C#的异常[重复]

令人惊讶的情况,异步方法中的异常处理不会捕获异常

C# 异步方法的异常处理

异步/等待异常和 Visual Studio 2013 调试输出行为

在 C# 中的类构造函数中调用异步方法 [重复]

编写高质量代码改善C#程序的157个建议——建议86:Parallel中的异常处理