サービスを停止する前にすべてを停止する必要がある多数のスレッドを持つWindowsサービスがあります。私はこのモデルを使用してスレッドを停止し、スレッドが停止したことを通知しています。
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
Thread1Running = true;
try
{
while (running)
{
AutoReset1.WaitOne(TimeSpan.FromSeconds(30.0));
if (running)
{
// do stuff
}
}
}
finally
{
Thread1Running = false;
}
}));
サービスを停止して停止するときが来たら、runningをfalseに設定し、そこにあるすべてのAutoResetでSet()を呼び出します。これにより、スレッドはスリープを停止するか、作業中の処理が終了したら停止するように即座に通知されます。これは本当にうまくいきます。しかし、私が最も心配しているのは、すべてが停止したことを確認することです。これは私が今していることです:
Int32 tries = 0;
while (tries < 5 && (Thread1Running || Thread2Running || Thread3Running))
{
tries++;
Thread.Sleep(TimeSpan.FromSeconds(5.0));
}
私がこれを嫌う主な理由は、それが時間ベースであり、私のスレッドの1つが長い操作の途中である場合(これは非常に可能性が高いです)、シャットダウンがその25秒で終了しない可能性があることです(そしてそれはこのコードが実行されるOnStopが終了するまでに、これらのスレッドがすべてシャットダウンされることが非常に重要です)。それらのスレッドの1つがハングした場合(それらはハングしませんが、あなたは決して知りません)、私は本当に立ち往生していて、サービスが停止することは決してないので、試行を削除することはできません。
スレッドがすべて停止したことを確認するためのより良い方法はありますか?できれば時間ベースではないものですか?それとも、もっと長くする必要があるかもしれないある種のタイムアウトがある運命にありますか(おそらく、30秒のスリープで10回試行します)?