【问题标题】:why would a re-thrown exception in a button click not get back to the user?为什么单击按钮时重新引发的异常不会返回给用户?
【发布时间】:2010-01-13 22:18:51
【问题描述】:

我有这个代码:

001 private void uiButton1_Click(object sender, EventArgs e)
002 {
003     string someString = "";
004     try
005     {
006         someString = ThisMethodThrowsAnException();
007     }
008     catch (Exception)
009     {        
010         throw;
011     }
012 }

代码确实到达了 catch 中的“抛出”,但标准的 winforms“未处理异常”对话框从未出现。

ThisMethodThrowsAnException() 正在引发 System.Exception 类型的异常。我有一个附加到 Application.ThreadException 的事件。在这种情况下,该事件没有受到影响。 uiButton 是一个标准的 winforms 按钮。我创建了一个在其事件处理程序中引发异常的按钮,并且该异常正在被 Application_ThreadException 捕获。所有的处理都发生在一个线程上。

在我的一生中,我不明白为什么这段代码不会导致正常的异常框(因为这是一个只有我使用的应用程序,所以它很有帮助)。在这个应用程序的其他地方,我看到了标准异常对话框。

我有一个如下所示的按钮单击处理程序:

 private void button2_Click(object sender, EventArgs e)
    {
        throw new Exception("I are broke!"); 
    }

还有一个看起来像这样的 ThreadException 处理程序:

 static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            MessageBox.Show("Exception: " + e.Exception.Message); 
        }

我正在使用 UnhandledExceptionMode.Automatic。当我单击 uiButton1 时,我没有通过 Application_ThreadException 收到异常消息。但是,如果我在对 ThisMethodThrowsAnException 的方法调用之前添加一个 throw new Exception,我会得到 MessageBox。

我确实通过 button2(通过 Application_ThreadException)获得了一个 MessageBox。

所以在 ThisMethodThrowsAnException 中发生了一些事情。我唯一能想到的是它正在启动一个新线程,但是当我通过它进行调试时情况并非如此。

如果异常发生在不同的线程上,它会返回到 uiButton1_Click 中的 catch 块吗?

【问题讨论】:

  • @Slaks:我不明白。类型已给出。该消息似乎无关紧要。
  • 如果删除 try/catch 会发生什么?只是想看看这是否有助于你了解发生了什么......
  • @psychotik:同样的结果。我添加了 try catch 以查看它是否在某个地方被吞下并且仅在调试运行时被捕获。事实并非如此。
  • 为您的应用程序配置了什么 UnhandledExceptionMode?​​span>
  • 我删除了我的答案 - 因为它不是答案,而是另一个问题:出于兴趣 - 我在相关列表中发现了 stackoverflow.com/questions/347502/… 并想知道是否存在相关性。从这个内部方法抛出一个带有内部异常的异常,看看它是否真的按预期工作?如果存在关系,则逃脱的异常应该是内部的,而不是外部的。希望这是有道理的。

标签: c# winforms


【解决方案1】:

调试器妨碍了。 Application 类知道调试器附加到程序,它使用 System.Diagnostics.Debugger.IsAttached()。如果是这种情况,它确实在消息循环周围使用 try/catch 块,Application.ThreadException 事件将运行。

这是故意的。如果 catch 块处于活动状态,您将很难对程序中的异常进行故障排除。如果没有 catch 块,调试器将始终停止并向您显示问题所在。

您可以重现运行时行为。在调用 Run() 之前将这行代码添加到 Main() 方法中:

 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

【讨论】:

  • 啊,但我没有说过我只在附加调试器时看到了这种行为。我尝试了所有三种应用程序异常模式。结果:两个给了我没有异常对话框,第三个关闭了我的应用程序(“MyApp 遇到了问题,需要关闭。”)
  • 澄清一下:在没有调试器的情况下运行应用程序时,uiButton1_Click 什么也不做。使用调试器运行时,调试器在第 10 行停止。
  • 您的 ThreadException 事件处理程序似乎正在吞噬异常而不报告它们。
  • @nobugz:不这么认为。在问题中添加了更多文本以进行澄清。
猜你喜欢
  • 1970-01-01
  • 2023-01-24
  • 2012-03-17
  • 2021-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 2011-01-28
相关资源
最近更新 更多