是否可以在 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 中创建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。

其他提示

您可以订阅 AppDomain.UnhandledException 事件. 。如果你有一个消息循环,你可以绑定到 Application.ThreadException 事件.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top