如何安全地处置System.Timers.Timer?

时间:2010-11-25 12:26:41

标签: .net multithreading timer dispose

当你处理一个“原始”.net计时器时,你可以传入一个等待句柄,一旦Win32计时器被销毁就被调用,你可以假设你的回叫不会被调用。 (计时器将被GC视为“死”)

如何使用System.Timers.Timer执行此操作?

2 个答案:

答案 0 :(得分:3)

在调用dispose之前设置一个标志,并在经过的处理程序中检查此标志。即使计时器触发,该标志也会阻止运行任何相关的处理程序代码。您可以通过为计时器编写包装器来形式化此模式。

确保您的标记被标记为易失性,因为它将从不同的线程访问。

答案 1 :(得分:0)

由于System.Timers.Timer和System.Windows.Forms.Timer都使用ThreadPool它没有操作系统计时器的句柄,所以没有处理掉的本机计时器资源 - 只是一个完成的线程。我不确定你是否可以捕获ThreadPool回收的线程,但我可能错了。

你可以自己动手(我没有测试过,在Dispose中使用ManualResetEvent可能更有用):

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