我在ApplicationEvents.vb文件中有以下代码来捕获UnhandledExceptions
Namespace My
Partial Friend Class MyApplication
Private Sub MyApplication_UnhandledException(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
MessageBox.Show("error")
End Sub
End Class
End Namespace
但是,这不会捕获在其他线程ThreadExceptions上发生的异常。我确实在其他线程和其他方法中有一些错误处理来防止和解决错误,但我想在应用程序意外失败时提供用于调试目的的信息。由于我在ApplicationEvents文件中的错误处理没有处理这些错误,我该怎么做才能为ThreadExceptions提供一些信息呢?
编辑:
我在下面尝试过Hans的解决方案,但遗憾的是没有骰子。我有代码,因为他或多或少地写了它,只是消息框是不同的。当我开始工作时,我可能会添加错误日志或让它向我们的支持收件箱发送消息。无论如何,这就是我所拥有的。附加到一个按钮我有一个小的子程序,它启动一个新线程并抛出异常以进行测试:
Private Sub Label2_Click(ByVal sender As System.Object, VyVal e As System.EventArgs) Handles Label2.Click
Dim newThread As New Thread(AddressOf ErrorThread)
newThread.Start()
End Sub
Private Sub ErrorThread()
Throw New System.NullReferenceException
End Sub
不幸的是,下面描述的方法还没有完成。我很抱歉这会被捕获,但是应用程序仍然无声地失败。
编辑:
Whelp,Hans删除了他的答案......我不知道为什么,但为了彻底的利益,我会发布我正在使用的代码,并简要说明当我逐步完成时会发生什么:
在ApplicationEvents.vb文件中:
Partial Friend Class MyApplication
Private Sub MyApplication_Startup(ByVal sender As Object, ByVal e As ApplicationServices.StartupEventArgs) Handles Me.Startup
If Not System.Diagnostics.Debugger.IsAttached Then
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf AllUnhandledExceptions
End If
End Sub
Private Sub AllUnhandledExceptions(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
Dim ex = DirectCast(e.ExceptionObject, Exception)
MessageBox.Show("Message" & ex.innerException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex))
End Sub
Private Sub MyApplication_UnhandledException(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
AllUnhandledExceptions(sender, New UnhandledExceptionEventArgs(e.Exception, True))
End Sub
End Class
这就是我现在正在使用的东西,并且所有归功于Hans Passant让我走得那么远。这是我一步一步发生的事情。启动处理程序运行,其他一些代码运行,并显示表单。单击表单上的按钮允许我逐步执行生成新线程的代码(通常我使用任务但在这种情况下我只是解雇了一个线程,相同的差异,据我所知不同的实现,更多的任务灵活性)它开始并抛出null ref异常。执行进行到AllUnhandledExceptions
子和MessageBox.Show
行。从该线击中F8会使我返回原始投掷线。 (我已经注释掉了启动例程中的If语句,可以像这样继续执行。)如果我构建应用程序,它仍然会无声地失败。 Windows告诉我应用程序必须结束,但不显示我的消息框。 UI线程中的错误仍会触发消息框。
任何进一步的想法,提示或技巧都表示赞赏。再次感谢您的时间和建议。
编辑:工作!经过轻微调整后,汉斯的回答确实有效。详细信息稍后发布......
因此,如果有人能够更深入地解释为什么在这种微小的变化之后它会起作用。我听见了。在调试中探讨之后,这就是我发现的内容,我有点尴尬,我没有及早发现它:
在新线程上抛出异常后,执行会转到AllUnhandledExceptions
sub,就像预期的那样。但是,当我在调试中调试我的代码时,我终于发现了一些东西 - 行Dim ex = DirectCast(e.ExceptionObject, Exception)
导致对象引用ex未被设置为对象的实例。我意识到我得到的空引用异常不是我原来的空引用异常,当我尝试在我的消息框中使用ex.innerexception.ToString时,它是ex上的空引用异常。我切换而不是使用ex我正在使用传递给sub的e对象,如:MessageBox.Show(Message & e.ExceptionObject.ToString, "Fatal Error", MessageButtons, MessageIcon)
并且看,它有效!此外,它适用于在UI线程和新线程上抛出的异常。
所以...这是我的决心。我仍然不确定为什么汉斯的答案会丢失,但如果他能够重新发布它,我想给他正式的信任,而不是他需要我确定的要点。
再次感谢大家!
答案 0 :(得分:1)
我会确保您的线程正确处理异常。你的主线程不会接受衍生线程中未处理的异常。