3

アプリケーション内のサービスを制御しようとしています。StartService(MSDN)を介してサービスを開始すると、サービスの開始に約10秒かかりますが、StartServiceを呼び出した後、すぐにメインアプリケーションに制御が戻ります。

ただし、ControlService(MSDN)を介してサービスを停止する場合(AFAIKにはStopServiceはありません)、サービスが停止するまで、約10秒かかるメインアプリケーションを完全にブロックします。

Start: StartServiceW( handle, 0, NULL)
Stop: ControlService( handle, SERVICE_CONTROL_STOP, status )

Windowsサービスを非ブロッキング/非同期で停止する方法はありますか?

4

3 に答える 3

1

サービスは、その制御ハンドラー ルーチンでクリーンアップを実行しています。終了に数分の 1 秒しかかからないサービスの場合は問題ありませんが、10 秒かかるサービスの場合は、必ず STOP_PENDING のステータスを設定し、非同期でクリーンアップする必要があります。

これが独自のサービスである場合は、その問題を修正する必要があります。すべてのクリーンアップが本当に必要であることを確認することから始めます。たとえば、停止する前にメモリを解放する必要はありません (サービスが他のサービスとプロセスを共有している場合を除きます)。クリーンアップが本当に十分に速くできない場合は、別のスレッドを起動して (またはメイン スレッドにシグナルを送って)、サービスのシャットダウンを実行し、サービスの状態を STOP_PENDING に設定します。

これが他の誰かのサービスである場合、唯一の解決策は、別のスレッドまたはサブプロセスから停止要求を発行することです。

于 2012-08-16T20:49:56.713 に答える
1

おそらく、新しいスレッドでサービスを停止することを検討します。これにより、メインスレッドのブロックが解消されます。

于 2012-08-15T16:38:18.757 に答える
1

SCM は、シリアル化された方法で制御要求を処理します。いずれかのサービスが制御要求の処理でビジーである場合ControlService()、SCM が新しい要求を処理できるようになるまでブロックされます。これはドキュメントにも記載されています:

SCM は、サービス制御通知を順次処理します。つまり、1 つのサービスがサービス制御通知の処理を完了するのを待ってから、次のサービス制御通知を送信します。このため、いずれかのサービスが制御コードの処理でビジー状態の場合、ControlService の呼び出しは 30 秒間ブロックされます。タイムアウトの期限が切れたときにビジー サービスがまだハンドラー関数から返されていない場合、ControlService は ERROR_SERVICE_REQUEST_TIMEOUT で失敗します。

于 2012-08-15T19:02:14.900 に答える