System.Timers.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(因此我的任务已被执行)?

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


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

 GC.KeepAlive(youtimer_Instance); 

查看Timer的Documentatio n的结尾以参考此场景。

示例代码中的注释说:

 
          通常,计时器在类级别声明, 
          只要需要它就可以保持在范围内。 
          如果以长时间运行的方法声明计时器,   
          必须使用KeepAlive来阻止JIT编译器  
          从允许积极的垃圾收集发生  
          在方法结束之前。  
 

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

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

System.Timers.Timer确实是一个很好的例子。 这使用封面下的System.Threading.Timer,如果你看reflection器,你可以在System.Timers.Timer上看到Dispose方法的以下内容

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

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

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