【发布时间】:2011-02-22 00:50:23
【问题描述】:
在我的主窗体上,我订阅了两个事件:Application.ThreadException 和 Application.Idle。理论上,任何未被捕获的异常都应该被冒泡到主窗体。但是,如果异常发生在 OnIdle 事件中,这将不起作用。系统只是崩溃。有谁知道如何解决这个问题?非常感谢。
【问题讨论】:
标签: winforms exception idle-processing
在我的主窗体上,我订阅了两个事件:Application.ThreadException 和 Application.Idle。理论上,任何未被捕获的异常都应该被冒泡到主窗体。但是,如果异常发生在 OnIdle 事件中,这将不起作用。系统只是崩溃。有谁知道如何解决这个问题?非常感谢。
【问题讨论】:
标签: winforms exception idle-processing
我同意不获取 ThreadException 事件并不是非常合乎逻辑的。但是它确实以这种方式工作,仅当消息循环分派事件并且事件处理程序中存在未处理的异常时才会引发 ThreadException。当没有消息要再分派时,会引发 Idle 事件,它遵循完全不同的代码路径。
您可以通过自己在 Idle 事件处理程序中捕获异常来解决此问题:
void Application_Idle(object sender, EventArgs e) {
try {
// Do stuff
}
catch (Exception ex) {
Application.OnThreadException(ex);
}
}
请注意,如果您让用户决定是退出还是继续程序,那么 ThreadException 是一个好坏参半的问题。另请注意,在您的程序中捕获所有异常还不够通用,您仍然需要 AppDomain.CurrentDomain.UnhandledException 来处理在 UI 线程以外的线程中引发的异常或之前引发的异常消息循环开始运行。
如果您这样做是为了确保用户不能单击“继续”,则只需使用 Application.SetUnhandledExceptionMode() 来完全禁用 ThreadException 事件。现在一切都通过 AppDomain.UnhandledException。这是更好的方法。
【讨论】:
异常只会在调用的方法堆栈中冒泡。
Idle 事件不会从您的表单代码中调用,因此不会冒泡到您的任何代码。
相反,您必须捕获未处理的异常。
看看:
其中一个会捕获您的异常。
【讨论】: