How do I safely dispose a System.Timers.Timer?

馋奶兔 提交于 2019-12-04 03:03:52

问题


When you dispose a “raw” .net timer, you can pass in a wait handle to be called once the Win32 timer has been destroyed and you can them assume that your call back will not be called. (And the timer will be considered "dead" by the GC)

How do I do this with a System.Timers.Timer?


回答1:


As System.Timers.Timer and System.Windows.Forms.Timer both use the ThreadPool it doesn't have a handle to an operating system timer, so there is no native timer resource that's disposed of - just a completed thread. I'm not sure you can capture a thread being recycled by the ThreadPool but I might be wrong.

You could maybe roll your own (I haven't tested this, and taking a ManualResetEvent in Dispose might be more useful):

void Run()
{
    ManualResetEvent resetEvent = new ManualResetEvent(false);

    System.Threading.Timer timer = new System.Threading.Timer(delegate { Console.WriteLine("Tick"); });
    timer.Dispose(resetEvent);

    MyTimer t = new MyTimer();
    t.Interval = 1000;
    t.Elapsed += delegate { t.Dispose(resetEvent); };

    resetEvent.WaitOne();
}


public class MyTimer : System.Timers.Timer
{
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
    }

    public virtual void Dispose(WaitHandle handle)
    {
        handle.SafeWaitHandle.Close();
        Dispose();
    }
}



回答2:


Set a flag before you call dispose, and check this flag in your elapsed handler. Even if the timer does fire, the flag will prevent any associated handler code from being run. You could formalize this pattern by writing a wrapper for the timer.

Make sure your flag is marked as volatile as it will be accessed from different threads.



来源:https://stackoverflow.com/questions/4277044/how-do-i-safely-dispose-a-system-timers-timer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!