2008-12-23 223 views
5

我有一個在Load事件處理程序中拋出ApplicationException的子表單(故意用於測試目的)。父窗體在Try ... Catch ex As Exception塊中包裝ChildForm.Show()方法。 catch塊只是顯示一條消息並關閉子窗體。所有在Visual Studio 2008(.net 3.5 sp1)中調試時的預期效果。但是,當我在Visual Studio之外運行它時,Catch塊似乎會錯過併發生未處理的異常。任何想法,爲什麼?捕獲塊沒有捕獲異常

謝謝。

示例代碼:

Public Class Form1 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Dim f2 As Form2 

     f2 = New Form2 

     Try 
      MessageBox.Show("Opening form 2") 
      f2.ShowDialog() 
     Catch ex As Exception 
      f2.Close() 
      MessageBox.Show("Form 2 closed.") 
     End Try 
    End Sub 

End Class 

Public Class Form2 

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     Throw New ApplicationException("Test Form_Load") 
    End Sub 

    Public Sub New() 

     ' This call is required by the Windows Form Designer. 
     InitializeComponent() 

     ' Add any initialization after the InitializeComponent() call. 
    End Sub 

End Class 

堆棧跟蹤:

 
System.ApplicationException: 
Test Form_Load at WindowsApplication1.Form2.Form2_Load(Object sender, EventArgs e) 
in UnhandledExceptionTest2\WindowsApplication1\Form2.vb 
System.Windows.Forms.Form.OnLoad(EventArgs e) 
System.Windows.Forms.Form.OnCreateControl() 
System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) 
System.Windows.Forms.Control.CreateControl() 
System.Windows.Forms.Control.WmShowWindow(Message& m) at 
System.Windows.Forms.Control.WndProc(Message&> m) at 
System.Windows.Forms.ScrollableControl.WndProc(Message&> m) at 
System.Windows.Forms.ContainerControl.WndProc(Message&> m) at 
System.Windows.Forms.Form.WmShowWindow(Message&> m) at 
System.Windows.Forms.Form.WndProc(Message&> m) at 
System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&> m) at 
System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&> m) at 
System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr 
lparam) 
+0

你能發表一些代碼嗎? – 2008-12-23 17:24:48

+0

是的 - 它描述的含義很模糊...... – 2008-12-23 17:27:59

回答

11

Form.Load事件的行爲與Windows窗體中大多數其他事件的行爲相同。它由消息循環調度,在這種情況下,當Windows發送WM_SHOWWINDOW消息時。消息循環中有一個異常處理程序,用於防止未捕獲的異常終止消息循環。該異常處理程序引發了Application.ThreadEvent事件。默認事件處理程序顯示未處理的異常對話框。長話短說,你無法捕捉到你的按鈕中的Load事件中引發的異常點擊處理程序。除了在Load事件處理程序中捕獲和處理異常外,很難做到這一點,我建議你在表單中添加一個公共方法。像Initialize()。將您的Load事件中的代碼移動到該方法中。在調用Show()方法之後調用Initialize(),現在可以捕獲異常。

0

我對C#道歉(我不知道VB的語法)

你在做這樣的事情:

ChildForm child = new ChildForm(); 
    try { 
     child.Show(); 
    } 
    catch(Exception ex) 
    {.....} 

如果s o,我相信Load事件會發生在New,而不是Show(); (顯示會激活)

+0

當我在調試器中執行操作時,Load事件發生在Show()上。 – NYSystemsAnalyst 2008-12-23 17:34:46

0

新窗口有自己的線程,它正在做它自己的加載。爲了驗證這一點,你可以嘗試在例外之前在Form2_Load中放入Thread.Sleep幾秒鐘。您的主線程窗口應該在您遇到異常之前繼續執行。

+0

可以理解,爲什麼代碼在Visual Studio中的工作方式與在VS之外運行時的工作方式不同? – NYSystemsAnalyst 2008-12-23 17:43:17

1

我有同樣的問題。我最終做的是捕捉所有例外。在C#中:

Application.ThreadException += new ThreadExceptionEventHandler(MyHandler); 

然後顯示錶單。

我很想聽聽有沒有人有更好的解決方案。