【发布时间】:2021-12-26 04:10:09
【问题描述】:
我很难理解 async/await 在各种非快乐路径情况下的工作原理。例如,我有以下代码:
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");
}
}
有两点我不明白:
-
ThrowsAsync方法是异步的,但是它不包含任何await。我假设在这种情况下,该方法将像“正常”同步方法一样执行。但是,它抛出的异常永远不会在catch块中捕获。 - 试图以某种方式捕获异常,我为
TaskScheduler.UnobservedTaskException添加了处理程序。但是,它永远不会被执行。这是为什么呢?
我知道如果我等待ThrowsAsync,就会捕获异常。不过,我正在尝试更好地了解它的工作原理。
我正在使用 .NET 5 和基于 Linux 的操作系统运行该代码。
【问题讨论】:
-
第二个this可以解释一下。对于第一个
ThrowsAsync是异步的并返回一个Task所以在等待之前它不应该抛出。 -
也适用于第一点 - this.
-
@GuruStron 关于
UnobservedTaskException。我试图遵循链接 SO 中的建议。我在Do方法的末尾添加了以下内容:Console.WriteLine("GC"); Thread.Sleep(100); GC.Collect(); GC.WaitForPendingFinalizers();。它没有改变任何东西。我看到控制台中打印了“GC”,仅此而已。 -
@Loreno 你可以和this article 一起去硬核,或者阅读斯蒂芬·克利里的博客和书籍(博客之前链接过)。
标签: c# .net asynchronous exception async-await