У меня есть служба 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 () для всех AutoResets. Это немедленно сигнализирует потокам о том, что они перестают спать или останавливаются после того, как они закончили обработку того, над чем они работают. Это работает очень хорошо. Но то, что меня больше всего волнует, это проверка того, что все прекратилось. Вот что я делаю сейчас:
Int32 tries = 0;
while (tries < 5 && (Thread1Running || Thread2Running || Thread3Running))
{
tries++;
Thread.Sleep(TimeSpan.FromSeconds(5.0));
}
Основная причина, по которой мне это не нравится, заключается в том, что он основан на времени, и если один из моих потоков находится в середине длительной операции (что весьма вероятно), завершение может не завершиться в эти 25 секунд. (и очень важно, чтобы все эти потоки были закрыты к тому моменту, когда OnStop, когда этот код запускается, завершается). Я не могу удалить попытки, потому что если один из этих потоков зависает (они этого не делают, но вы никогда не знаете), то я действительно застрял, и служба никогда не остановится.
Есть ли лучший способ проверки того, что все потоки остановлены, предпочтительно не основанный на времени? Или я обречен на какой-то тайм-аут, который, возможно, просто должен быть намного длиннее (возможно, 10 попыток с 30-секундным сном)?