How do I gracefully stop a System.Threading.Timer?

后端 未结 4 793
星月不相逢
星月不相逢 2021-02-13 03:57

I have a Windows Service implemented in C# that needs to do some work every so often. I\'ve implemented this using a System.Threading.Timer with a callback method t

相关标签:
4条回答
  • 2021-02-13 04:36

    Possible solution for protecting the callback method from working on a disposed timer:

    https://stackoverflow.com/a/15902261/193178

    0 讨论(0)
  • 2021-02-13 04:39

    As described in "Concurrent Programming on Windows":
    Create a dummy class InvalidWaitHandle, inheriting from WaitHandle:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Threading;
    
    namespace MyNameSpace
    {
        class InvalidWaitHandle : WaitHandle
        {
    
        }
    }
    

    Hence you can Dispose a System.Threading.Timer properly like this:

    public static void DisposeTimer()
    {
       MyTimer.Dispose(new InvalidWaitHandle());
       MyTimer = null;
    }
    
    0 讨论(0)
  • 2021-02-13 04:44

    With this code

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

    it is almost certain that you will Dispose the timer while it is sleeping.

    You will have to safeguard the code after Sleep() to detect a Disposed timer. Since there is no IsDisposed property a quick and dirty static bool stopping = false; might do the trick.

    0 讨论(0)
  • 2021-02-13 04:56

    You do not need to dispose of the timer to stop it. You can call Timer.Stop() or set Timer.Enabled to false, either of which will stop the timer from running.

    0 讨论(0)
提交回复
热议问题