Windows窗体计时器不会停止。怎么可能?

时间:2011-08-05 14:08:38

标签: c# .net winforms debugging timer

在调试期间,我可以看到执行Timer.Stop()Timer.Enabled = false命令后,Timer仍在运行(Timer.Enabled = true)。怎么可能?

3 个答案:

答案 0 :(得分:7)

当您在工作线程上停止计时器时,这是可能的。例如:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
    }
    Timer timer1;
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        timer1 = new Timer();
        timer1.Interval = 3000;
        timer1.Start();
        var t = new System.Threading.Thread(stopTimer);
        t.Start();
    }
    private void stopTimer() {
        timer1.Enabled = false;
        System.Diagnostics.Debug.WriteLine(timer1.Enabled.ToString());
    }
}

输出:

必须由UI线程停止计时器,该类会自动处理它。与Control.BeginInvoke()非常相似。有一个明确的竞争,Tick事件处理程序可以在你停止后运行。如果您创建的第一个计时器是在工作线程上创建的,那么这也可能发生在UI线程上。例如一个闪屏。这不健康,你应该解决这个问题。

答案 1 :(得分:3)

通过调用Stop禁用定时器后调用Start将导致Timer重新启动中断的间隔。如果您的Timer设置为5000毫秒间隔,并且您在大约3000毫秒内调用Stop,则调用Start将导致Timer在提升Tick事件之前等待5000毫秒。

另请记住

在Windows窗体应用程序中的任何计时器上调用Stop可以立即处理来自应用程序中其他Timer组件的消息,因为所有Timer组件都在主应用程序线程上运行。如果你有两个Timer组件,一个设置为700毫秒,一个设置为500毫秒,你在第一个Timer上调用Stop,你的应用程序可能会先收到第二个组件的事件回调。如果这证明有问题,请考虑在System.Threading命名空间中使用Timer类。

http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.stop.aspx

答案 2 :(得分:1)

public void EnableTimer(bool state)
{
    if (this.InvokeRequired) {
        this.Invoke(new Action<bool>(EnableTimer), state);
    } else {
        this.Timer1.Enabled = state;
    }
}

试试这段代码......