关于.net Windows服务中的vb.net:UnhandledException处理程序

关于.net Windows服务中的vb.net:UnhandledException处理程序

UnhandledException handler in a .Net Windows Service

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

通常,我会使用自定义构建的异常处理组件来进行日志记录,电话回家等。该组件向System.AppDomain.CurrentDomain.UnhandledException添加了一个处理函数,但据我所知,它无法获得Windows Service的支持,因此 我最终在我的2(或4)个服务入口点中使用了这种模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<wyn>
    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
</wyn>

我的自定义异常处理组件是否可以更好地处理此问题,因此我不必用凌乱的异常处理管道填充OnStart?


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<wyn>
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
</wyn>

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

因此,我"想"这说明了为什么我的异常处理组件无法在启动和停止时捕获UnhandledException,但是我不确定这是否解释了为什么在OnStart中设置的计时器在触发时不会导致UnhandledException。


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


推荐阅读