多くのデータを処理する Windows サービスを c# で作成しました。停止すると、20/30 秒間試してから例外がスローされます。
OnStop イベントに ServiceBase.RequestAdditionalTime() を実装したい。
Windows サービスが例外をスローする正確なタイムアウトを知りたいので、その直前に追加の時間を要求できます。
検索しましたが、このデフォルトの停止タイムアウト値は見つかりませんでした。
多くのデータを処理する Windows サービスを c# で作成しました。停止すると、20/30 秒間試してから例外がスローされます。
OnStop イベントに ServiceBase.RequestAdditionalTime() を実装したい。
Windows サービスが例外をスローする正確なタイムアウトを知りたいので、その直前に追加の時間を要求できます。
検索しましたが、このデフォルトの停止タイムアウト値は見つかりませんでした。
それを達成するために次のコードを書きました。
protected override void OnStop()
{
int timeout = 10000;
var task = Task.Factory.StartNew(() => MyTask());
while (!task.Wait(timeout))
{
RequestAdditionalTime(timeout);
}
}
上記のコードは、メインスレッドと並行してタスクを開始します (タスクはすぐに実行を開始します)。次の行は、タスクが完了したかどうかを 10 秒ごとに確認し、完了していない場合は追加の 10 秒を要求し、タスクが取得されるまで確認を続けます。完了しました。
多くの人がHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout
レジストリ キーについて言及していますが、Microsoft のこの「サービス コントロール ハンドラー」の記事によると、レジストリ エントリは、Windows 自体がシャットダウンまたは再起動されているときに、サービスがシャットダウンするのにかかる最大時間を制御するだけです。
<...> サービスがシャットダウンを停止しないようにするために、サービス コントローラーの待機時間には制限があります。サービス スナップインを使用してサービスをシャットダウンする場合、制限は 125 秒です。オペレーティング システムが再起動している場合、制限時間は
WaitToKillServiceTimeout
値 <...>で指定されます。
Windows が再起動中またはシャットダウン中でない場合、Windows がサービスのシャットダウンを待機する既定の時間は 30 秒です。ただし、アプリケーションは追加の時間を要求することができ、これは合計で最大 125 秒 (すべての要求の合計) まで受け入れられます。
Windows Server 2003 以降では、この Microsoft サポート記事(およびこの ServerFault question )で説明されているように、レジストリ キーを介してこの既定のタイムアウトを変更できます。この記事ではサーバー バージョンについてのみ言及しているため、これが Windows 7/8/10 に当てはまるかどうかは不明です。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ServicesPipeTimeout
マシンで再起動/シャットダウンが開始さWaitToKillServiceTimeout
れた場合、レジストリ キーの値 (存在する場合) は、Windows が許可するアプリケーションの最大時間を指定し、OS の既定値を上書きします。
おそらくこれは、アプリケーションがデフォルト (または管理者がWaitToKillServiceTimeout
レジストリ エントリで指定したもの) を超えてシャットダウンを任意に遅らせることができないようにするためです。
サブキーのレジストリに設定されています。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
文字列値でWaitToKillServiceTimeout
。定義されていない場合、デフォルトは 20000 (ミリ秒) です。私のマシンでは、12000 (12s) に設定されているようです。私はそれに触れたことがありません。
RequestAdditionalTime
サービスのシャットダウンに必要と予想される最大時間で、常に を実行してください。予想より早く終了してもエラーではありません。
デフォルトでは 12000 ミリ秒だと思います。変更するには、レジストリ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout にアクセスして値を変更する必要があります
ただし、ここでプログラミングを開始または停止する場合は、独自のタイムアウトを定義できます。開始するための独自のタイムアウトを定義します
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
ここで、停止するための独自のタイムアウトを定義します
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);