Как изящно остановить 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 перегрузка ям говорит:

Таймер не удаляется до тех пор, пока не будут завершены все текущие обратные вызовы в очереди.

Изменить: кажется, что это утверждение из документации может быть неверным. Может кто-нибудь проверить?

Я знаю, что мог бы обойти эту проблему, добавив некоторую сигнализацию между обратным вызовом и кодом утилизации, как предложил Хенк Холтерман ниже, но я неЯ не хочу делать это без крайней необходимости.

Ответы на вопрос(4)

Ваш ответ на вопрос