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

The timer is not disposed until all currently queued callbacks have completed.

Edit: It appears that this statement from the documentation may be incorrect. Can someone verify?

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

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

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