【问题标题】:async try catch - exception variable is null异步尝试捕获 - 异常变量为空
【发布时间】:2021-03-18 19:50:08
【问题描述】:

此代码仅用于学习/测试目的:

我故意在 Task.Run(...) 中抛出异常并从 WindowsForm ButtonClickEventHandler 调用它:

async void button_Click(object sender, EventArgs e)
{
    try
    {
        await Task.Run(
            () =>
            {
                throw new Exception("Foo");
            }
        );
    }
    catch (Exception ex) { }
}

当我调试应用程序并对 catch 语句设置断点时,我看到变量“ex”的值为 null。为什么会这样?如何捕获异常内容? (如果我之后使用 Task.Wait() 或 ContinueWith() 它会被正确捕获,但我想知道在使用 await 时如何捕获它)

这是奇怪的部分: 如果我插入“Debug.WriteLine(ex.Message);” catch 中的语句, ex 不再为空。 如果我删除“Debug.WriteLine(ex.Message);”再次声明并运行代码 ex 不为空。显然在某些运行中 ex 具有价值,有时它只是空值。

这是线程问题还是只是 Visual Studio 错误?

环境:Windows 10、VS 2019、.NET 5.0、Windows 窗体应用程序

【问题讨论】:

  • 尝试将Console.WriteLine(ex); 放在catch 块内。如果它真的进入了catch-block,我确定它不为null
  • @Xerillio:如果我在 catch 中放置一个 Debug.WriteLine(ex.Message) 语句,则会显示消息并且变量“ex”不为空。但是我仍然想知道为什么在第一种情况下 VS 将 ex 显示为 null,尽管异常被正确捕获。这是一个错误吗?
  • @A.B.如果我没记错的话,因为你的 catch 块中没有语句,调试器永远不会真正进入该代码块的范围,因此该范围的变量不会被扩展。这是一个很好的提醒,可以避免使用空代码块吞下异常 - 这是不好的做法。

标签: c# .net async-await


【解决方案1】:

断点的精确位置很重要。如果您只是断点该行,则 ex 将为空。如果你对 catch 块的左大括号进行断点,ex 将有一个值。您还可以越过行断点到大括号上以获取值。

这是左大括号上的断点

这是“行”上的断点

【讨论】:

    猜你喜欢
    • 2014-12-01
    • 1970-01-01
    • 2021-12-13
    • 2011-12-05
    • 2014-06-03
    • 2014-05-11
    • 2020-07-31
    • 2020-10-11
    • 1970-01-01
    相关资源
    最近更新 更多