2015-09-07 192 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

相關問題