52
protected override void OnStart(string[] args)
{
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    Thread.Sleep(10000);

    throw new Exception();
}

void CurrentDomain_UnhandledException(object sender,
                                      UnhandledExceptionEventArgs e)
{
}

Windows サービスの上記のコードにデバッガーをアタッチし、CurrentDomain_UnhandledException にブレークポイントを設定しましたが、ヒットしませんでした。未処理であることを示す例外がポップアップ表示され、サービスが停止します。最適化されている場合に備えて、イベント ハンドラーにコードを入れてみました。

これは、Windows サービスで未処理の例外処理を設定する適切な方法ではありませんか?

4

5 に答える 5

60

UnhandledException現在の AppDomain でイベントが発生しない理由は、サービスの実行方法にあります。

  1. ユーザーは、Windows サービス コントロール マネージャー (SCM) から開始コマンドを送信します。
  2. コマンドはフレームワークのServiceBase実装によって受信され、メソッドにディスパッチされOnStartます。
  3. OnStartメソッドが呼び出されます。

によってスローされたすべての例外はOnStart、基本クラスで処理され、イベント ログに記録され、SCM に返されるエラー ステータス コードに変換されます。そのため、例外が AppDomain の未処理の例外ハンドラーに伝達されることはありません。

サービスのワーカー スレッドからスローされた未処理の例外は、AppDomain の未処理の例外ハンドラーによってキャッチされることがわかると思います。

于 2011-02-25T13:27:06.010 に答える
10

Windowsサービスでは、OnStartメソッドで多くのコードを実行する必要はありません。必要なのは、サービススレッドを起動して戻るためのコードだけです。

そうすれば、サービススレッドで発生する例外を問題なく処理できます。

例えば

public static void Start()
{
    AppDomain currentDomain = AppDomain.CurrentDomain;
    currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);

    running = true;
    ThreadStart ts = new ThreadStart(ServiceThreadBody);
    thread = new Thread(ts);
    thread.Name = "ServiceThread";
    thread.Priority = ThreadPriority.BelowNormal;
    thread.Start();
}
于 2010-03-26T22:29:43.970 に答える
4

このスレッドは少し古いことを知っていますが、.NETでWindowsサービスを開発した個人的な経験に基づいてコメントを追加すると便利だと思いました。 最善のアプローチは、サービスコントロールマネージャーの下での開発をできるだけ避けることです-このためには、サービスの開始方法を模倣する単純なハーネスが必要です-サービスクラスのインスタンスを作成できるもの(すでにServiceBaseから派生しています) )そして、OnStart、OnStopなどのメソッドを呼び出します。このハーネスは、必要に応じてコンソールアプリまたはWindowsアプリにすることができます。

これは、.NETでサービスの起動の問題をデバッグするために私が見つけたほとんど唯一の方法です。コード、Visual Studio、および実際のサービスコントロールマネージャー間の相互作用により、プロセスが不可能になります。

HTH。

于 2010-08-26T10:34:12.630 に答える
2

サービスのクラッシュを回避したり、エラーを報告したりしますか?

レポートについては、最上位の try/catch ステートメントを追加するのが最善の策だと思います。それらを Windows イベント ログやログ ファイルに記録してみることができます。

サービスを正常に停止するまで、 ExitCodeプロパティをゼロ以外の値に設定することもできます。システム管理者が [サービス] コントロール パネルからサービスを開始し、ゼロ以外の終了コードでサービスが突然停止した場合、Windows はエラーの説明を含むエラー メッセージを表示できます。

于 2010-03-16T18:38:43.153 に答える