Как изящно остановить System.Threading.Timer?
У меня есть служба Windows, реализованная на C #, которая должна выполнять какую-то работу время от времени. Я'мы реализовали это с помощьюSystem.Threading.Timer
с методом обратного вызова, который отвечает за планирование следующего обратного вызова. У меня возникли проблемы с грациозной остановкой (т. Е. Утилизацией) таймера. Вот'Вот некоторый упрощенный код, который вы можете запустить в консольном приложении, который иллюстрирует мою проблему:
const int tickInterval = 1000; // one second
timer = new Timer( state => {
// simulate some work that takes ten seconds
Thread.Sleep( tickInterval * 10 );
// when the work is done, schedule the next callback in one second
timer.Change( tickInterval, Timeout.Infinite );
},
null,
tickInterval, // first callback in one second
Timeout.Infinite );
// simulate the Windows Service happily running for a while before the user tells it to stop
Thread.Sleep( tickInterval * 3 );
// try to gracefully dispose the timer while a callback is in progress
var waitHandle = new ManualResetEvent( false );
timer.Dispose( waitHandle );
waitHandle.WaitOne();
Проблема в том, что я получаюObjectDisposedException
отtimer.Change
в потоке обратного вызова в то время какwaitHandle.WaitOne
блокирует Что я делаю неправильно?
Документация дляDispose
перегрузка ям говорит:
Таймер не удаляется до тех пор, пока не будут завершены все текущие обратные вызовы в очереди.
Изменить: кажется, что это утверждение из документации может быть неверным. Может кто-нибудь проверить?
Я знаю, что мог бы обойти эту проблему, добавив некоторую сигнализацию между обратным вызовом и кодом утилизации, как предложил Хенк Холтерман ниже, но я неЯ не хочу делать это без крайней необходимости.