这是使用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(因此我的任务已被执行)?
答案 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()。如果让它保持运行,它将不必要地利用资源,并且在关闭应用程序时也可能会出现异常。