【问题标题】:FormClosing and Unhandled ExceptionFormClosing 和未处理的异常
【发布时间】:2012-01-06 03:31:40
【问题描述】:

我从具有 FormClosing 处理程序的表单继承我的类(它是可重写的,因此我可以重写它并在调用基本方法之前在那里执行 MsgBox("Ha"))。在我的 Shared Sub New() 我有:

' Add the event handler for handling UI thread exceptions to the event.
AddHandler Application.ThreadException, AddressOf Application_ThreadException

' Add the event handler for handling non-UI thread exceptions to the event. 
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException

'For Console applications you should use the System.AppDomain.UnhandledException event
AddHandler Thread.GetDomain().UnhandledException, AddressOf CurrentDomain_UnhandledException

如果我在 try/catch 之外的表单中抛出异常,我会注意到两种不同的行为:

  1. 如果我使用 VS 调试器,我得到一个未处理的异常,并且似乎调用了我的未处理的异常处理程序。似乎没有调用 formClosing 事件处理程序。
  2. 如果我不使用 VS 调试器,则 FormClosing 处理程序正在 调用但未调用未处理的异常处理程序。

我很困惑为什么在 #2 中没有调用未处理的异常处理程序。理想情况下,我希望(在这两种情况下)调用未处理的异常,然后调用 FormClosing 事件处理程序。我错过了什么?

(一些示例代码)——这演示了如果您在 VS 中使用调试器运行(只需按 F5)或在没有调试器的情况下运行(只需按 CTRL-F5),将如何引发不同的异常。这并不能完美地重现问题,但也许我的问题与基类处理不同的 ThreadException 有关。

Form1(在您的项目中设置为启动)。

Imports System.Threading

Public Class Form1
    Inherits Form2

    Shared Sub New()
        ' Add the event handler for handling UI thread exceptions to the event. 
        AddHandler Application.ThreadException, AddressOf Application_ThreadException

        ' Add the event handler for handling non-UI thread exceptions to the event.  
        AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException

    End Sub

    Private Shared Sub CurrentDomain_UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
        MsgBox("UnhandledException caught")
    End Sub

    Private Shared Sub Application_ThreadException(ByVal sender As Object, ByVal e As ThreadExceptionEventArgs)
        MsgBox("ThreadException caught")
    End Sub

    Protected Overrides Sub Login()
        Throw New Exception("Ha!")

        MyBase.Login()
    End Sub

    Protected Overrides Sub Form2_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs)
        MsgBox("Form1Closing")

        MyBase.Form2_FormClosing(sender, e)
    End Sub
End Class

表格2:

Public Class Form2

  Protected Overridable Sub Form2_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        MsgBox("Form2Closing")
    End Sub

    Private Sub Form2_Shown(sender As System.Object, e As System.EventArgs) Handles MyBase.Shown
        Login()
    End Sub

    Protected Overridable Sub Login()
        MsgBox("Form2 LoggingIn")
    End Sub
End Class

【问题讨论】:

  • 在表单中使用 Shared 构造函数有什么特别的原因吗?
  • 共享构造函数确保我只调用未处理的异常处理程序 1 次
  • 嗯,这与应该发生的情况完全相反。发布代码,以便我们都可以自己尝试。我绝对对它的外观感兴趣,这已经被敲打了数十亿次。
  • 当我尝试这段代码时,它应该可以正常工作。在没有调试器的情况下获取“ThreadException catched”。

标签: .net vb.net winforms


【解决方案1】:

我很抱歉没有使用评论部分,也许它应该在那里(没有足够的代表)。只是想我会把我的 2c 研究投入:

  • 使用 VS2010 SP1。
  • 使用默认设置创建了 WinApp 项目。
  • 移植上述代码,在Form2类定义中添加“继承Form”语句。
  • 使用调试器 - 获取“UnhandledException 捕获”消息,然后调试器在 Throw New Exception(“Ha!”) 行中断,继续将我抛出无限循环(再次获取“UnhandledException 捕获”消息等)。
  • 没有调试器 - 获取“UnhandledException 捕获”,然后继续执行,当关闭表单时,获取“Form1Closing”和“Form2Closing”。

一切似乎都按预期进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    相关资源
    最近更新 更多