为什么System.Threading.Timer自行停止?
在Windows服务项目中使用System.Threading.Timer
之前,我正在做一个小型测试项目。 它工作得非常好,但计时器会在一两分钟后自行停止。
测试项目的完整来源是:
using System; using System.Windows.Forms; using System.Threading; namespace studyTimers { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { TimerCallback timerDelegate = new TimerCallback(tick); System.Threading.Timer testTimer = new System.Threading.Timer(timerDelegate, null, 1000, 1000); } void tick(Object obj) { if (label1.InvokeRequired) { label1.Invoke(new MethodInvoker(() => tick(obj))); } else { label1.Text = DateTime.Now.ToString(); } } } }
显然,目标是用当前时间更新标签。 我注意到稍后更新停止了。 为什么会这样?
如果你需要Windows窗体上的计时器,然后将System.Windows.Forms.Timer
放到窗体上 – 没有理由使用System.Threading.Timer
除非你需要更好的分辨率超过55毫秒。
计时器“停止”的原因是因为它被垃圾收集。 您允许它超出Form1_Load
方法的范围,因为您只将它声明为局部变量。 为了使计时器“保持活动”,它必须是表单类上的私有字段,以便GC知道它仍然需要。
换一种说法:
public partial class Form1 : Form { private System.Threading.Timer testTimer; ... public void Form1_Load(object sender, EventArgs e) { TimerCallback timerDelegate = new TimerCallback(tick); testTimer = new System.Threading.Timer(timerDelegate, null, 1000, 1000); } }
但同样,在这种情况下,使用System.Windows.Forms.Timer
更简单,它是工具箱中的一个实际组件,您可以将其放到表单上。
编辑 – 正如评论现在显示的那样,如果这只是一个测试应用程序并且真正的应用程序在Windows服务中, 则不能使用System.Windows.Forms.Timer
。 请记住不要让你的System.Threading.Timer
超出范围。
垃圾收集器收集了计时器对象,你应该保留对它的引用。 这篇文章将有所帮助: http : //msdn.microsoft.com/en-us/library/system.threading.timer.aspx
它不应该。 你的代码有问题吗? 编辑:我在谈论工具箱中的计时器。