捕获块不捕获异常 [英] Catch block not catching exception

查看:24
本文介绍了捕获块不捕获异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个子窗体在 Load 事件处理程序中抛出 ApplicationException(有意用于测试目的).父窗体将 ChildForm.Show() 方法包装在 Try...Catch ex As Exception 块中.catch 块只显示一条消息并关闭子窗体.在 Visual Studio 2008 (.net 3.5 sp1) 中调试时,一切都按预期工作.但是,当我在 Visual Studio 之外运行它时,似乎错过了 Catch 块并发生了未处理的异常.知道这是为什么吗?

谢谢.

示例代码:

公共类Form1Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 处理Button1.Click将 f2 调暗为 Form2f2 = 新表格 2尝试MessageBox.Show("打开表单2")f2.ShowDialog()Catch ex 作为例外f2.关闭()MessageBox.Show("Form 2 关闭.")结束尝试结束子结束班公开课Form2Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) 处理 MyBase.Load抛出新的应用程序异常(测试 Form_Load")结束子公共子新建()' Windows 窗体设计器需要此调用.初始化组件()' 在 InitializeComponent() 调用之后添加任何初始化.结束子结束班

堆栈跟踪:

<前>System.ApplicationException:在 WindowsApplication1.Form2.Form2_Load(Object sender, EventArgs e) 测试 Form_Load在 UnhandledExceptionTest2WindowsApplication1Form2.vbSystem.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) 在System.Windows.Forms.Control.WndProc(Message&> m) atSystem.Windows.Forms.ScrollableControl.WndProc(Message&> m) atSystem.Windows.Forms.ContainerControl.WndProc(Message&> m) atSystem.Windows.Forms.Form.WmShowWindow(Message&> m) atSystem.Windows.Forms.Form.WndProc(Message&> m) atSystem.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&> m) atSystem.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&> m) atSystem.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr参数)

解决方案

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

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

I have a child form that is throwing an ApplicationException in the Load event handler (intentionally for testing purposes). The parent form wraps the ChildForm.Show() method in a Try...Catch ex As Exception block. The catch block simply displays a message and closes the child form. All works as expected when debugged in visual studio 2008 (.net 3.5 sp1). However, when I run it outside of visual studio, the Catch block seems to get missed and an unhandled exception occurs. Any idea why that is?

Thank you.

Example Code:

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

Stack Trace:

 System.ApplicationException:
 Test Form_Load   at WindowsApplication1.Form2.Form2_Load(Object sender, EventArgs e)
 in UnhandledExceptionTest2WindowsApplication1Form2.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)

解决方案

The Form.Load event behaves the same way as most other events in Windows Forms. It is dispatched by the message loop, in this case when Windows sends the WM_SHOWWINDOW message. There is an exception handler in the message loop that prevents an uncaught exception from terminating the message loop. That exception handler raises the Application.ThreadEvent event. The default event handler displays the unhandled exception dialog.

Long story short, you cannot catch an exception raised in the Load event in your button Click handler. Other than catching and handling exceptions in the Load event handler itself, very hard to do right, I'd recommend you add a public method to the form. Something like Initialize(). Move the code from your Load event into that method. Call Initialize() after calling the Show() method, exceptions are now yours to catch.

这篇关于捕获块不捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆