System.Timers.Timer生命周期

时间:2011-02-10 10:18:15

标签: c# .net timer

这是使用System.Timers.Timer的正确方法吗? 我的意思是......我创建了计时器,设置了间隔以及在Elapsed事件上调用的方法。

double ms = 1000;
var t = new System.Timers.Timer(ms);
t.AutoReset = false;
t.Elapsed += (sender, e) =>  { runTask(); }; 
t.Start();   

下一步是什么?是否应该在计时器上拨打电话?我想我不能,或者Elapsed事件永远不会发生。 我应该在一些全局变量中注册Timer以避免丢失对它的引用,因此GC可以在调用Elapsed之前配置定时器吗? 如果是这样,一旦处理了Elapsed事件,我怎么能处理Timer(因此我的任务已被执行)?

3 个答案:

答案 0 :(得分:4)

如果您在长时间运行的过程中使用计时器(例如Web应用程序或Windows服务),如果您不想获得内存泄漏,则需要确保取消订阅Timer的已用事件处理程序,如果您希望垃圾收集器能够回收为Timer对象分配的内存。

System.Timers.Timer实现了IDisposable,这里的指导原则是,如果你有一个实现IDisposable的类,任何对实现IDisposable的对象具有依赖性的类都应该实现IDisposable本身并在它时调用对象Dispose()方法本身被称为。

一个完美的例子确实是System.Timers.Timer。这使用了封面下面的System.Threading.Timer,如果你查看反射器,你可以看到System.Timers.Timer上的Dispose方法的以下内容

public void Dispose()
{
    this.timerBase.Dispose();
}

这里,timerBase只是System.Threading.Timer的一个实例,因此Dispose调用级联到实现IDisposable的类的所有依赖项。

答案 1 :(得分:1)

简短的回答是你不需要做任何事情。当函数超出范围时,它将由垃圾收集器收集。如果你想要它可用,那么在课堂上声明它。

<小时/> 通常当您在类级别声明一个计时器时,它会在类处理时由GC收集。但是当你在一个函数中声明你的计时器时,Timer仍然会运行,但如果你正在执行一个很长的过程,那么GC可以积极地处理它,所以你需要使用

GC.KeepAlive(youtimer_Instance);

查看Timer's Documentatio n的结尾以参考此方案。

示例代码中的注释表示:


        Normally, the timer is declared at the class level,
        so that it stays in scope as long as it is needed.
        If the timer is declared in a long-running method,  
        KeepAlive must be used to prevent the JIT compiler 
        from allowing aggressive garbage collection to occur 
        before the method ends. 

答案 2 :(得分:0)

您应该在表单/页面的关闭/卸载或您认为合适的任何地方调用t.Stop()。如果让它保持运行,它将不必要地利用资源,并且在关闭应用程序时也可能会出现异常。