Comment est-ce que j'arrête gracieusement un System.Threading.Timer?

J'ai un Windows Service implémenté en C# qui doit faire un peu de travail chaque tellement souvent. J'ai mis en place ce à l'aide d'un System.Threading.Timer avec une méthode de rappel qui est responsable de la planification de la fonction de rappel. J'ai de la difficulté avec élégance l'arrêt (c'est à dire l'élimination) de la minuterie. Voici quelques simplifié de code que vous pouvez exécuter dans une application console qui illustre mon problème:

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();

Le problème est que je reçois un ObjectDisposedException de timer.Change sur le rappel de filetage waitHandle.WaitOne est bloquant. Ce que je fais mal?

La documentation pour la Dispose surcharge je suis en utilisant dit:

La minuterie n'est pas disposé jusqu'à ce que tous actuellement en file d'attente des rappels avez terminé.

Edit: Il semble que cette déclaration de la documentation peut être incorrect. Quelqu'un peut-il vérifier?

Je sais que je pourrais contourner le problème en ajoutant de la signalisation entre le rappel et à l'élimination code Henk Holterman suggéré ci-dessous, mais je ne veux pas le faire, sauf si absolument nécessaire.

source d'informationauteur William Gross