【问题标题】:UnhandledException handler in a .Net Windows Service.Net Windows 服务中的 UnhandledException 处理程序
【发布时间】:2010-09-08 16:00:36
【问题描述】:

是否可以在 Windows 服务中使用 UnhandledException 处理程序?

通常我会使用自定义构建的异常处理组件来执行日志记录、电话回家等。该组件向 System.AppDomain.CurrentDomain.UnhandledException 添加了一个处理程序,但据我所知,这并没有取得任何成果Windows 服务,所以我最终在我的 2 个(或 4 个)服务入口点中使用了这种模式:

Protected Overrides Sub OnStart(ByVal args() As String) ' Add code here to start your service. This method should set things ' in motion so your service can do its work. Try MyServiceComponent.Start() Catch ex As Exception 'call into our exception handler MyExceptionHandlingComponent.ManuallyHandleException (ex) 'zero is the default ExitCode for a successfull exit, so if we set it to non-zero ExitCode = -1 'So, we use Environment.Exit, it seems to be the most appropriate thing to use 'we pass an exit code here as well, just in case. System.Environment.Exit(-1) End Try End Sub

我的自定义异常处理组件有什么方法可以更好地处理这个问题,这样我就不必在 OnStart 上填满杂乱的异常处理管道了吗?

【问题讨论】:

    标签: .net vb.net exception-handling windows-services


    【解决方案1】:

    好的,我现在对此进行了更多研究。 当您在 .Net 中创建 Windows 服务时,您会创建一个继承自 System.ServiceProcess.ServiceBase 的类(在 VB 中,它隐藏在 .Designer.vb 文件中)。然后,您可以覆盖 OnStart 和 OnStop 函数,以及 OnPause 和 OnContinue(如果您选择)。 这些方法是从基类中调用的,所以我对反射器做了一些探索。 OnStart 由 System.ServiceProcess.ServiceBase 中称为 ServiceQueuedMainCallback 的方法调用。我机器上的版本“System.ServiceProcess, Version=2.0.0.0”反编译如下:

    Private Sub ServiceQueuedMainCallback(ByVal state As Object) Dim args As String() = DirectCast(state, String()) Try Me.OnStart(args) Me.WriteEventLogEntry(Res.GetString("StartSuccessful")) Me.status.checkPoint = 0 Me.status.waitHint = 0 Me.status.currentState = 4 Catch exception As Exception Me.WriteEventLogEntry(Res.GetString("StartFailed", New Object() { exception.ToString }), EventLogEntryType.Error) Me.status.currentState = 1 Catch obj1 As Object Me.WriteEventLogEntry(Res.GetString("StartFailed", New Object() { String.Empty }), EventLogEntryType.Error) Me.status.currentState = 1 End Try Me.startCompletedSignal.Set End Sub

    因此,因为 Me.OnStart(args) 是从 Try Catch 块的 Try 部分中调用的,所以我假设 OnStart 方法中发生的任何事情都被该 Try Catch 块有效包装,因此不会发生任何异常技术上未处理,因为它们实际上是在 ServiceQueuedMainCallback Try Catch 中处理的。所以 CurrentDomain.UnhandledException 至少在启动例程期间实际上从未发生过。 其他 3 个入口点(OnStop、OnPause 和 OnContinue)都以类似的方式从基类调用。

    所以我“认为”这解释了为什么我的异常处理组件无法在启动和停止时捕获 UnhandledException,但我不确定它是否解释了为什么在 OnStart 中设置的计时器在触发时不会导致 UnhandledException .

    【讨论】:

    • 我发现服务中的 UnhandledException 事件确实会在其他线程中收到异常,只要您尽早连接事件处理程序。我将它连接到服务构造函数而不是 OnStart() 方法中。这也从您的 OnStart() 中删除了丑陋的异常管道。
    【解决方案2】:

    您可以订阅AppDomain.UnhandledException event。如果有消息循环,可以绑定Application.ThreadException event

    【讨论】:

    • 鉴于我对您的回复已被删除(几年前)我想我会把它作为评论放回去,这本来应该是这样的:感谢 Garo 的回答,但正如我在我最初的问题中说,我们的异常处理程序确实向 System.AppDomain.CurrentDomain.UnhandledException 添加了一个处理程序,在 Windows 服务的上下文中使用它时它根本不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 2013-05-31
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    相关资源
    最近更新 更多