为什么System.Threading.Timer会自行停止?

c# .net service timer

11273 观看

3回复

2589 作者的声誉

System.Threading.Timer在用于Windows Service项目之前,我正在做一个小型测试项目。它的运行非常出色,但是计时器在一两分钟后自行停止。

测试项目的完整资源为:

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

显然,目标是使用当前时间更新标签。我注意到一点之后更新就停止了。为什么会这样呢?

作者: Tom Corelis 的来源 发布者: 2010 年 2 月 4 日

回应 (3)


37

106872 作者的声誉

决定

如果您需要Windows窗体上的计时器,然后将a System.Windows.Forms.Timer放到窗体上- System.Threading.Timer除非您需要比55毫秒更好的分辨率,否则没有理由使用a 。

计时器“停止”的原因是因为它正在被垃圾收集。您允许它超出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超出范围。

作者: Aaronaught 发布者: 04.02.2010 01:45

-1

1118 作者的声誉

不应该这样 您的代码有问题吗? 编辑:我正在谈论工具箱中的计时器。

作者: Bloodyaugust 发布者: 04.02.2010 01:46

1

338 作者的声誉

垃圾收集器收集了计时器对象,您应该保留对其的引用。这篇文章会有所帮助:http : //msdn.microsoft.com/zh-cn/library/system.threading.timer.aspx

作者: megaKertz 发布者: 22.08.2014 05:04
32x32