我遇到过以下情况。在显示MDI子项的大型应用程序中,子窗体中的异常也会关闭父窗体。
我正在尝试捕获异常并以特殊错误形式显示错误消息。期望的行为是在没有处理父表单的情况下捕获异常。在子表单中,我有一个触发异常的按钮
throw new ApplicationException("test");
如果我将断点放入主窗体(MDI父级)Dispose方法
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
我得到以下调用堆栈
myApp.dll!myForm.Dispose(bool disposing)
System.dll!System.ComponentModel.Component.Dispose()
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadWindows.Dispose()
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows()
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.Dispose(bool postQuit)
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reasion, System.Windows.Forms.ApplicationContext context)
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reasion, System.Windows.Forms.ApplicationContext context)
System.Windows.Forms.dll!System.Windows.Forms.Application.Run()
处理 true 。
之后我想要捕获的异常确实在顶级try-catch语句中被捕获但是 mdi父表单已经关闭(为什么?)
这里有一些代码显示了我的顶级try-catch是如何工作的:
public class MainApplication
{
[STAThread]
static void Main(string[] args)
{
Application.ThreadException += MyThreadExceptionHandler;
try
{
OurMain(args);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message + "\n" + ex.StackTrace, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
private static void MyThreadExceptionHandler(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message + "\n" + e.Exception.StackTrace, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
private static void OurMain(string[] args)
{
//run the application
}
}
我的问题在这里,我正在寻找解决问题的策略,并了解为什么MDI父表格正在关闭(最后阻止它关闭)。
到目前为止,我认为我知道:
注意:我已经以非常一般的方式提出了这个问题。请告诉我哪些具体信息与您相关,以便能够回答这个问题。
我的具体案例中的解决方案:
在我的情况下,解决方案不仅要处理Application.ThreadException
,还要使用this answer中描述的其他选项。在我的情况下,处理Dispatcher.CurrentDispatcher.UnhandledException
完成了这项工作。 Application.ThreadException
似乎只适用于纯WinForms,但我封装了一个Web View,并且绑定到Web View触发了异常,Application.ThreadException
没有对此做出反应。
答案 0 :(得分:0)
当发生错误时,异常将“冒泡”代码层次结构,直到它被捕获(使用Try / Catch)或者到达顶部。
当它到达顶部(在调试中)时,应用程序只是关闭 - 关闭所有打开的表单。
如果运行.exe,您将看到标准消息:“应用程序中出现未处理的异常”。使用继续/退出按钮。
处理此问题的方法是使用Try / Catch块来捕获预期的错误。
对于到达顶级主函数的异常,它将在表单中冒泡,导致表单被处理(因为表单对象不再在范围内)。表单由表单实例化代码或垃圾收集器处理。这是自动清理内存的所有部分。