简体   繁体   English

未捕获异步方法中抛出的异常 - 为什么?

[英]Exception thrown in async method is not caught - why?

I have a hard time understanding how async/await works in various non-happy-path cases.我很难理解 async/await 在各种非快乐路径情况下是如何工作的。 For example, I have the following code:例如,我有以下代码:

    class Program
    {
        static void Main(string[] args)
        {
            Do();
            Console.ReadLine();
        }

        private static void Do()
        {
            TaskScheduler.UnobservedTaskException += (s, e) =>
            {
                Console.WriteLine($"Unobserved Exception : {e.Exception.Message}");
                e.SetObserved();
            };
            
            try
            {                
                ThrowsAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Caught in try/catch  : {ex.Message}");
            }
        }

        private static async Task ThrowsAsync()
        {    
            Console.WriteLine("Throwing");
            throw new Exception("FAILURE");
        }
    }

There are two things that I do not understand:有两件事我不明白:

  1. The ThrowsAsync method is async, however, it does not contain any await . ThrowsAsync方法是异步的,但是,它不包含任何await I would assume that in such a case the method would execute like a "normal" synchronous method.我会假设在这种情况下,该方法将像“正常”同步方法一样执行。 However, the exception that it throws is never caught in the catch block.但是,它抛出的异常永远不会在catch块中catch
  2. Trying to somehow catch the exception, I added the handler for TaskScheduler.UnobservedTaskException .试图以某种方式捕获异常,我为TaskScheduler.UnobservedTaskException添加了处理程序。 However, it is never executed.但是,它永远不会被执行。 Why is that?这是为什么?

I know that the exception would be caught if I awaited ThrowsAsync .我知道如果我等待ThrowsAsync会捕获异常。 However, I'm experimenting to get a better understanding of how it works.但是,我正在尝试更好地了解它的工作原理。

I'm running that code using .NET 5 and Linux-based OS.我正在使用 .NET 5 和基于 Linux 的操作系统运行该代码。

  1. As described for example in this blog post by Stephen Cleary - the state machine for async methods will capture exceptions from your code and place them on the returned task, ie method invocation will not throw, you will be able to catch exception if await the result.例如如 Stephen Cleary 在这篇博客文章中所述- async方法的状态机将从您的代码中捕获异常并将它们放在返回的任务上,即方法调用不会抛出,如果await结果,您将能够捕获异常.

  2. As for TaskScheduler.UnobservedTaskException - check out this answer and be sure to run code in Release mode.至于TaskScheduler.UnobservedTaskException - 查看这个答案并确保在Release模式下运行代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM