Dot-Net

.Net Windows 服務中的 UnhandledException 處理程序

  • September 12, 2008

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

引用自:https://stackoverflow.com/questions/58280