web-dev-qa-db-ja.com

構成が間違っていて何もしない場合にWindowsサービスOnStartを終了する正しい方法は何ですか?

これは私が得たものです:

protected override void OnStart(string[] args)
{
    if (SomeApp.Initialize())
    {
        SomeApp.StartMonitorAndWork();
        base.OnStart(args);
    }
}

protected override void OnStop()
{
    SomeApp.TearDown();
    base.OnStop();
}

ここでInitializeは設定ファイルを読み取ります。それが間違っている場合は何もすることがないので、サービスを停止する必要があります。構成に問題がない場合、StartMonitorAndWorkが開始されます。

Timer(new TimerCallback(DoWork), null, startTime, loopTime);

doWorkはデータベースを定期的にポーリングします。

初期化に失敗し(ログファイルを確認)、[管理ツール]-> [サービス]からサービスを停止しようとすると、次のようになります。

ローカルコンピューターでSomeServiceを停止できませんでした。サービスはエラーを返しませんでした。 
これは、Windowsの内部エラーまたはサービスの内部エラーである可能性があります。 
問題が解決しない場合は、システム管理者に連絡してください。
質問は次のとおりです。
「Initializeがfalseを返した場合、何もせずにOnStartを終了しますか?

または、次のようなものがあるはずです:

private void ExitService()
{
    this.OnStop();
    System.Environment.Exit(1);
}

protected override void OnStart(string[] args)
{
    if (ObjectFolderApp.Initialize())
    {
        SomeApp.StartMonitorAndWork();
        base.OnStart(args);
    }
    else
    {
        ExitService();
    }
}

ありがとう&BR-マティ

編集:私はこのようなものを思いついた:

protected override void OnStart(string[] args)
{
    try
    {
        if (SomeApp.Initialize())
        {
            SomeApp.StartMonitorAndWork();
            base.OnStart(args);
        }
        else
        {
            Stop();
        }
    }
    catch
    {
        Stop();
    }
}

protected override void OnStop()
{
    try
    {
        SomeApp.TearDown();
        base.OnStop();
    }
    catch
    {
        base.OnStop();
    }
}
29
char m

すべてのアプローチをテストした後、私は個人的に電話することを好みます

Environment.FailFast("Configuration is wrong.");

主な目標は、失敗の説明がイベントログに書き込まれ、FailFastがサービスのリカバリ設定に影響を与えることです。したがって、リカバリを構成し、構成が正しくなると、サービスが自動的に開始されます。

10
Nisus

私はそれがきれいではないことを知っていますが、OnStartで例外をスローすることも機能します。

サービスが「自動ログ」に設定されている場合、これにより、例外メッセージもEventLogに自動的に書き込まれます。

protected override void OnStart(string[] args)
{
    if (ObjectFolderApp.Initialize())
    {
        SomeApp.StartMonitorAndWork();
        base.OnStart(args);
    }
    else
    {
        throw new Exception("What went wrong");
    }
}
3
ParmesanCodice

Initialize()がfalseを返し、失敗したときに適切なメッセージが表示された場合は、イベントログにエラーを記録します。失敗した場合は、OnStop()を呼び出すことをお勧めします。サービスを適切にシャットダウンすることをお勧めします。

この関連SO質問 、および devニュースグループスレッド も参照してください。

2
Mikael Svenson

私はあなたにこのようなものをお勧めします:

protected override void OnStop()
{
    try
    {
        EventLog.WriteEntry("MyService", "Service is going to stop because of ...", EventLogEntryType.Information);        
        // Dispose all your objects here        
    }
    catch (Exception ex)
    {
        EventLog.WriteEntry("MyService", "Exception : " + ex.ToString(), EventLogEntryType.Error);                
    }
    finally
    {
        GC.Collect();                
        base.OnStop();
    }
}
0