但是这个文档是理论性的,并不绑定到 Windows Forms 和 Visual Studio 2022,在 Visual Studio 中我们有特殊的按钮来处理异常
该类只允许捕获一个异常 UnhandledException。我需要捕获第二个异常,因为我有复杂的多线程应用程序。
我创建了这个简单的测试来捕获 ThreadException
Public Shared Sub ThreadExceptionEventHandler(ByVal sender As Object, ByVal e As ThreadExceptionEventArgs)
MsgBox(e.Exception, MsgBoxStyle.OkOnly, "ThreadExceptionEventHandler")
End Sub
Private Async Sub MainForm_Load(sender As Object, e As EventArgs) Handles Me.Load
AddHandler Application.ThreadException, AddressOf ThreadExceptionEventHandler '
Await Task.Run(Sub()
Throw New Exception("test exception")
End Sub)
....
并在 MyApplication 类中尝试捕获 Unhadled 异常
Partial Friend Class MyApplication
Private Sub MyApplication_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) Handles Me.UnhandledException
MsgBox(e.Exception, MsgBoxStyle.OkOnly, "UnhandledException")
End Sub
...
所以,看起来任何异常都必须被我的代码捕获,不是吗?但不是。使用 Visual Studio 启动代码显示未处理的错误
在控制台上启动程序不显示任何内容,程序关闭时没有任何错误消息,这意味着捕获任何异常不起作用。为什么?
还有。请注意,ThreadException 在 MyApplication 类中不可用。
根据@Jimi的建议,最终的解决方案就在那里
Partial Friend Class MyApplication
Public Shared Sub ThreadExceptionEventHandler(ByVal sender As Object, ByVal e As ThreadExceptionEventArgs)
Dim Data() As Byte = System.Text.UTF8Encoding.UTF8.GetBytes(e.Exception.Message)
My.Computer.FileSystem.WriteAllBytes(IO.Path.Combine(IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Now.ToBinary.ToString & ".txt"), Data, True)
End Sub
Private Overloads Sub OnStartup()
AddHandler System.Windows.Forms.Application.ThreadException, AddressOf ThreadExceptionEventHandler
End Sub
Private Sub MyApplication_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
My.Application.DoEvents()
End Sub
Private Sub MyApplication_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) Handles Me.UnhandledException
Dim Data() As Byte = System.Text.UTF8Encoding.UTF8.GetBytes(e.Exception.Message)
My.Computer.FileSystem.WriteAllBytes(IO.Path.Combine(IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Now.ToBinary.ToString & ".txt"), Data, True)
End Sub
在 Jimi 建议中添加 3 条小评论:
(1) 当然重写是不可能的,只能重写。
(3) Msgbox(也许所有 Windows 窗体)在此工作流程中不起作用,我在文件上有简单的写入异常,在这种情况下它正在工作。
(3) 我在多线程应用程序中经常使用的替代方法(但不幸的是,在我当前的程序中不可能使用替代方法) - 将 Windows 窗体应用程序作为控制台应用程序启动,并且在绑定到所有 Windows 窗体事件后,比控制台应用程序进一步打开 Windows 窗体将完成。在这种情况下,控制台会在短时间内出现黑色屏幕,并且仅出现 Windows 窗体。
但是在 MyApplication 上重载 onStartup 是可行且更简单的方法,谢谢吉米。