2008-09-12 6 views
24

WindowsサービスでUnhandledExceptionハンドラを使用することはできますか?.NET WindowsサービスのUnhandledExceptionハンドラ

通常、私はロギング、電話機のホームなどを行うカスタムビルド例外処理コンポーネントを使用します。このコンポーネントは、System.AppDomain.CurrentDomain.UnhandledExceptionにハンドラを追加しますが、これまで何も達成できないことがわかります

 

    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 
 

私のカスタム例外処理コンポーネントは、より良いので、私は入力する必要はありません。これに対処することができる方法があります:Windowsサービスは、私は私の2(または4)サービスのエントリポイントでこのパターンで終わるので、私のOnStartの乱雑な例外処理配管?

答えて

15

[OK]を、私は今これについてもう少し研究を行った。 .NETでWindowsサービスを作成すると、System.ServiceProcess.ServiceBaseを継承するクラスが作成されます(VBでは.Designer.vbファイルに表示されません)。次にOnStartとOnStop関数、OnPauseとOnContinueをオーバーライドします。 これらのメソッドは基本クラス内から呼び出されるので、少しリフレクターを覗いてみました。 OnStartは、ServiceQueuedMainCallbackというSystem.ServiceProcess.ServiceBaseのメソッドによって呼び出されます。 Me.OnStart(引数が)私がいると仮定するTry Catchブロックのトライ部分内から呼び出されているため

ので
 

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 
 

:私のマシン上のvesion「System.ServiceProcess、バージョン= 2.0.0.0は、」このような逆コンパイルOnStartメソッド内で発生するものは、そのTry Catchブロックによって効果的にラップされるため、発生した例外はServiceQueuedMainCallback Try Catchで実際に処理されるため、技術的に処理されません。したがって、少なくとも起動ルーチンの間は、CurrentDomain.UnhandledExceptionは実際には起こりません。 他の3つのエントリポイント(OnStop、OnPauseおよびOnContinue)は、すべて同様の方法で基本クラスから呼び出されます。

なぜ私の例外処理コンポーネントがStartおよびStopでUnhandledExceptionをキャッチできないのか説明していますが、OnStartでセットアップされているタイマーでUnhandledExceptionが発生しない理由を説明できるかどうかはわかりません火災。

+3

私は、サービス内のUnhandledExceptionイベントが非常に早い時期にイベントハンドラを終了する限り、他のスレッドで例外を受け取ることがわかりました。私は、OnStart()メソッドではなくサービスコンストラクタでそれを配線しました。これにより、あなたのOnStart()から醜い例外配管も取り除かれます。 – saille

2

AppDomain.UnhandledException eventに登録することができます。メッセージループがある場合は、Application.ThreadException eventに関連付けることができます。

+0

あなたの回答が削除されました(数年前)私はそれをコメントとして戻したいと思っていました。私たちの例外ハンドラは、Windowsサービスのコンテキストでそれを使用しているときには単に動作しませんSystem.AppDomain.CurrentDomain.UnhandledExceptionにハンドラを追加します。 – Scott

関連する問題