2008-12-23 228 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); 

然后显示表单。

我很想听听有没有人有更好的解决方案。