Остановка потока, ManualResetEvent, логическое значение volatile или cancellationToken
У меня есть поток (STAThread) в службе Windows, который выполняет большой объем работы. Когда служба Windows перезапускается, я хочу изящно остановить этот поток.
Я знаю несколько способов
Летучий логическийManualResetEventCancellationTokenНасколько я выяснил Thread.Abort нет дела ...
Какова лучшая практика? Работа выполняется в другом классе, чем тот, в котором запущен поток, поэтому необходимо либо ввести параметр cancellationToken в конструктор, либо, например, иметь переменную volatile. Но я просто могуне понять, что умнее.
Обновить
Просто чтобы прояснить немного, я обернул очень простой пример того, что яЯ говорю о. Как было сказано ранее, это делается в службе Windows. Прямо сейчас яя думаю о энергозависимом логическом значении, которое проверено в цикле или cancellationToken .... Я не могу дождаться окончания цикла, как указано ниже, это может занять несколько минут, из-за чего системные администраторы сервера считают, что что-то не так с сервис, когда им нужно перезапустить его .... Я могу без проблем просто отбросить всю работу в цикле без проблем, однако я не могу сделать это с потоком. Аборт это "злой" и, кроме того, вызывается интерфейс COM, поэтому требуется небольшая очистка.
Class Scheduler{
private Thread apartmentThread;
private Worker worker;
void Scheduling(){
worker = new Worker();
apartmentThread = new Thread(Run);
apartmentThread.SetApartmentState(ApartmentState.STA);
apartmentThread.Start();
}
private void Run() {
while (!token.IsCancellationRequested) {
Thread.Sleep(pollInterval * MillisecondsToSeconds);
if (!token.IsCancellationRequested) {
worker.DoWork();
}
}
}
}
Class Worker{
//This will take several minutes....
public void DoWork(){
for(int i = 0; i < 50000; i++){
//Do some work including communication with a COM interface
//Communication with COM interface doesn't take long
}
}
}
ОБНОВИТЬ
Только что проверил производительность, используя cancellationToken, где состояние isCancelled равно "рассмотрел» в коде, намного быстрее, чем использование waitOne для ManualResetEventSlim. Несколько быстрых вычислений, если итерация на cancellationToken 100.000.000 раз в цикле for обходится мне в ок. 500 мс, где WaitOne стоит ок. 3 секунды Так что производительность в этом сценарии быстрее использовать cancellationToken.