.Net Windows服务中的UnhandledException处理程序

时间:2008-09-12 04:06:20

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

是否可以在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?

2 个答案:

答案 0 :(得分:15)

好的,我现在对此进行了一些研究。 在.Net中创建Windows服务时,您将创建一个继承自System.ServiceProcess.ServiceBase的类(在VB中,它隐藏在.Designer.vb文件中)。然后,如果选择,则覆盖OnStart和OnStop函数,以及OnPause和OnContinue。 这些方法是从基类中调用的,所以我用反射器做了一点点。 OnStart由System.ServiceProcess.ServiceBase中名为ServiceQueuedMainCallback的方法调用。我的机器上的vesion“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)都以类似的方式从基类调用。

所以我认为'这解释了为什么我的异常处理组件无法在Start和Stop上捕获UnhandledException,但我不确定它是否解释了为什么在OnStart中设置的计时器在它们触发时不会导致UnhandledException 。

答案 1 :(得分:2)

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