2015-09-07 191 views
-1

我遇到以下情况。在显示MDI子窗体的大型应用程序中,子窗体中的异常也会关闭父窗体。WinForms:为什么从RunMessageLoopInner调用Dispose?

我想捕捉异常并以特殊错误形式显示错误消息。期望的行为是在没有处理父表单的情况下捕获异常。在子窗体我有一个按钮,触发一个异常

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父窗体正在关闭(并最终阻止它关闭)。

我想我知道到目前为止:

  • 我想这不是一个线程问题(顺便说一句我也处理ThreadException事件,并获得什么也没有),因为我能赶上在UI异常线。

注意:我以非常一般的方式提出了这个问题。请告诉我哪些具体信息与您有关,以便能够回答这个问题。


解决方案在我的具体情况:

在我的情况的解决方案是,不仅处理Application.ThreadException也可采用其他选项像this answer描述。在我的情况处理Dispatcher.CurrentDispatcher.UnhandledException做了这份工作。 Application.ThreadException似乎只适用于纯WinForms,但我封装了Web视图,并且绑定到Web视图触发了异常,并且Application.ThreadException没有对此做出反应。

+0

在'program.cs'中,连接[Application.ThreadException](https://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception(v = vs.110) ).aspx)事件并从那里采取行动... –

+0

@Idle_Mind:正如可以在问题中看到的,我处理这个事件... – Sjoerd222888

+0

道歉...你有:_以后我想捕捉的异常确实被捕获为预期在顶级try-catch语句中,但主表单已被删除._这个try/catch在哪里?你可以显示该代码吗? –

回答

0

发生错误时,异常将“冒泡”代码层次结构,直到它被捕获(使用Try/Catch)或它到达顶端。

当它到达顶端(在调试中)时,应用程序简单地关闭 - 关闭任何打开的窗体。

如果你运行。您将看到标准消息:“未处理的异常发生在您的应用程序中。”与继续/退出按钮。

处理此问题的方法是使用Try/Catch块来捕获预期的错误。


对于异常到你顶级的主要功能就已经冒泡式过去的形式引起形式来配置(如表格对象不再在范围内)。表单由表单实例代码或垃圾收集器处理。这是自动清理内存的一部分。

+0

请您在发布答案之前阅读问题......尽管陈述全部正确,但我没有看到与问题的关系(除非两者均包含“异常”一词)。 – Sjoerd222888

+0

@ Sjoerd:这是一个问题:_“我正在寻找解决问题的策略,并了解为什么表单正在关闭(并最终阻止它关闭)._我的回答与问题完全相关。如果不清楚那么我可以详细说明 – Ulric

+0

我编辑了我的问题,也许它不够清楚 – Sjoerd222888

相关问题