Catch块没有捕获异常

时间:2008-12-23 17:23:39

标签: .net vb.net visual-studio visual-studio-2008 .net-3.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)

4 个答案:

答案 0 :(得分:11)

Form.Load事件的行为与Windows窗体中的大多数其他事件的行为相同。它由消息循环调度,在这种情况下,当Windows发送WM_SHOWWINDOW消息时。消息循环中有一个异常处理程序可以防止未捕获的异常终止消息循环。该异常处理程序引发Application.ThreadEvent事件。默认事件处理程序显示未处理的异常对话框。

长话短说,您无法在按钮单击处理程序中捕获Load事件中引发的异常。除了在Load事件处理程序本身中捕获和处理异常之外,很难做到,我建议你在表单中添加一个公共方法。像Initialize()之类的东西。将Load事件中的代码移动到该方法中。在调用Show()方法之后调用Initialize(),现在可以捕获异常了。

答案 1 :(得分:1)

我有同样的问题。我最终做的是捕获所有异常。在C#中:

Application.ThreadException += new ThreadExceptionEventHandler(MyHandler);

然后显示表格。

我很想知道是否有人有更好的解决方案。

答案 2 :(得分:0)

我为C#道歉(我不知道Vb语法)

你正在做这样的事情:

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

如果是这样,我相信Load事件会发生在New,而不是Show(); (显示会触发激活)

答案 3 :(得分:0)

新窗口有自己的线程,它正在进行自己的加载。要验证这一点,您可以尝试在异常之前将Thread.Sleep放入Form2_Load几秒钟。在遇到异常之前,您的主线程窗口应该继续执行。