Winforms 傻瓜计时器

Posted

技术标签:

【中文标题】Winforms 傻瓜计时器【英文标题】:Winforms Timer for Dummies 【发布时间】:2010-11-13 13:39:06 【问题描述】:

我试图让一个计时器在 winform 中每秒滴答一次,当我寻找有关如何执行此操作的建议时,我发现了大量关于线程的内容。好吧,我不关心线程,因为我要做的就是在一分钟内将一个值从 60 倒数到 0,然后停止。我不认为我们需要进入云计算来解决这个问题,但我真的是一个网络表单,所以我对这个问题有点生疏。谁能给我举个例子

这是我尝试过的

private void button1_Click(object sender, EventArgs e)
    
        this.timeLeft = 60;
        this.label1.Visible = false;
        this.button1.Visible = false;
        gt = new Timer();
        gt.Tick += new EventHandler(CountDown);
        gt.Interval = 1000;
        gt.Start();
    

private void CountDown(object sender, EventArgs e)

    do
    
        this.TimeBar.Value = timeLeft;                
        this.timeLeft -= 1;
     while (this.timeLeft > 0);
    if (this.TimeBar.Value > 0) return;
    gt.Stop();
    this.label1.Visible = true;
    this.button1.Visible = true;

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

如果您使用 winforms 的计时器,您不需要线程。

在您的页面上放置一个 Timer 控件,将其命名为“timer”并粘贴以下代码:

public MainForm()

    InitializeComponent();

    timer.Interval = 1000;
    timer.Start();

    timeLeft = 60;
    timer.Tick += Timer_Tick;

    // start things
    label1.Hide();
    button1.Hide();
    timer.Start();



public void Timer_Tick(object sender, EventArgs e)

    timeLeft--;

    if (timeLeft <= 0) 
        timer.Stop();
        label1.Show();
        button1.Show();
    

我想如果你有 webby 背景,如果你想了解桌面上的东西是如何编程的,那么事件驱动的编程可能是你需要开始阅读的内容。

【讨论】:

谢谢,是的,线程问题只是噪音,我现在已经整理好了,但我也有一些很好的阅读指南。【参考方案2】:

发生的情况是您正在递减timeLeft 变量,直到它在计时器的第一个滴答声中达到零。去掉do...while 循环,你就有了一个基本工作的例子。

但是,如果您要执行任何数量的 Windows 窗体工作,您需要了解线程以及它如何影响 UI。如果您没有遇到无用的异常和行为不端的 UI 组件的故事,您很快就会发现自己又回到了这里。 Jon Skeet 有一个出色的threading series。我强烈推荐它。它有一个专门介绍计时器的部分,因此可能会给您一些额外的见解。

【讨论】:

并且不要忘记在倒计时结束后关闭计时器,否则会遇到负数。 谢谢,这里已经很晚了,当然我不需要循环,doh!还要感谢 Skeet 先生的线程文档的链接。 :) @Martinho - Obligado,是的,我也遇到了 :)【参考方案3】:

除了取消循环(根据 jasonh 的回答),如果应用程序有点忙,您的方法可能会变得有点不准确。尽管您以毫秒为单位指定它们的时间间隔,但 WinForms 计时器的分辨率为 18 毫秒并且具有非常低的优先级,消息循环仅在没有其他事情可做时才检查计时器。

因此,保留一个 StartTime (DateTime) 值并使用它来计算每个 Timer 事件中的剩余时间。您只需要 61 个滴答声即可达到一分钟。

【讨论】:

是的,我读到的计时器精确到大约 55 毫秒。它只是在做一些非常微不足道的事情,所以在一分钟内 +-3 秒就可以了,其他进程也不会破坏银行。不过谢谢:)【参考方案4】:

您不想在事件处理程序中进行任何循环。每个计时器“滴答”调用一次处理程序 - 每 1000 毫秒,正如您配置的那样。因此,您希望每次调用减少一次 timeLeft 变量,然后在 timeLeft 达到零时关闭整个过程。

// untested
private void CountDown(object sender, EventArgs e)

    this.TimeBar.Value = timeLeft;
    this.timeLeft--;
    if (this.TimeBar.Value == 0)
    
        gt.Stop();
        this.label1.Visible = true;
        this.button1.Visible = true;
    

【讨论】:

谢谢,只是有点脑残,做一个小项目给我女儿用,因为这里的电视很差。你的代码和我最终得到的差不多。

以上是关于Winforms 傻瓜计时器的主要内容,如果未能解决你的问题,请参考以下文章

从计时器更新 Winforms 控件 [重复]

WinForms 中的计时器

c#检测表单中的计时器

如何在.Net中正确实现自定义计时器

多个计时器的多个数据库检查

WPF Timer 控件在哪里?