捕获块没有捕获异常
我有一个在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)
Form.Load事件的行为与Windows窗体中大多数其他事件的行为相同。它由消息循环调度,在这种情况下,当Windows发送WM_SHOWWINDOW消息时。消息循环中有一个异常处理程序,用于防止未捕获的异常终止消息循环。该异常处理程序引发了Application.ThreadEvent事件。默认事件处理程序显示未处理的异常对话框。长话短说,你无法捕捉到你的按钮中的Load事件中引发的异常点击处理程序。除了在Load事件处理程序中捕获和处理异常外,很难做到这一点,我建议你在表单中添加一个公共方法。像Initialize()。将您的Load事件中的代码移动到该方法中。在调用Show()方法之后调用Initialize(),现在可以捕获异常。
我对C#道歉(我不知道VB的语法)
你在做这样的事情:
ChildForm child = new ChildForm();
try {
child.Show();
}
catch(Exception ex)
{.....}
如果s o,我相信Load事件会发生在New,而不是Show(); (显示会激活)
当我在调试器中执行操作时,Load事件发生在Show()上。 – NYSystemsAnalyst 2008-12-23 17:34:46
新窗口有自己的线程,它正在做它自己的加载。为了验证这一点,你可以尝试在例外之前在Form2_Load中放入Thread.Sleep
几秒钟。您的主线程窗口应该在您遇到异常之前继续执行。
可以理解,为什么代码在Visual Studio中的工作方式与在VS之外运行时的工作方式不同? – NYSystemsAnalyst 2008-12-23 17:43:17
我有同样的问题。我最终做的是捕捉所有例外。在C#中:
Application.ThreadException += new ThreadExceptionEventHandler(MyHandler);
然后显示表单。
我很想听听有没有人有更好的解决方案。
你能发表一些代码吗? – 2008-12-23 17:24:48
是的 - 它描述的含义很模糊...... – 2008-12-23 17:27:59