.Net Windows 服務中的 UnhandledException 處理程序
是否可以在 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。