У меня есть служба Windows с несколькими потоками, которые необходимо остановить до остановки службы. Я использую эту модель для остановки своих потоков и сигнализации о том, что они были остановлены:
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
Thread1Running = true;
try
{
while (running)
{
AutoReset1.WaitOne(TimeSpan.FromSeconds(30.0));
if (running)
{
// do stuff
}
}
}
finally
{
Thread1Running = false;
}
}));
Когда приходит время остановить мою службу, я просто устанавливаю для ее запуска значение false и вызываю Set() для всех автосбросов. Это немедленно сигнализирует потокам о том, что они должны перестать спать или остановиться, как только они закончат обработку того, над чем они работают. Это работает очень хорошо. Но больше всего меня беспокоит то, что все остановилось. Вот что я делаю сейчас:
Int32 tries = 0;
while (tries < 5 && (Thread1Running || Thread2Running || Thread3Running))
{
tries++;
Thread.Sleep(TimeSpan.FromSeconds(5.0));
}
Основная причина, по которой мне это не нравится, заключается в том, что это основано на времени, и если один из моих потоков находится в середине длительной операции (что вполне вероятно), завершение работы может не завершиться за эти 25 секунд (и это очень важно, чтобы все эти потоки были закрыты к моменту завершения OnStop, когда запускается этот код). Я не могу удалить попытки, потому что если один из этих потоков зависнет (они не зависнут, но кто знает), то я действительно застрял, и служба никогда не остановится.
Есть ли лучший способ проверить, что все потоки остановлены, желательно тот, который не основан на времени? Или я обречен на какой-то тайм-аут, который, возможно, просто должен быть намного дольше (возможно, 10 попыток с 30-секундным сном)?