【问题标题】:Can I use a timer to update a label every x milliseconds我可以使用计时器每 x 毫秒更新一次标签吗
【发布时间】:2012-09-13 09:08:43
【问题描述】:

这是我的代码:

Stopwatch timer = new Stopwatch();
timer.Start();
while (timer.ElapsedMilliseconds < 3000) {
    label1.Text = Convert.ToString( timer.ElapsedMilliseconds );
}
timer.Stop();

我的意图是实时更新标签的文本,所以如果timer.ElapsedMilliseconds == 1350,那么label1.Text = 1350。我怎样才能做到这一点?提前致谢!

【问题讨论】:

  • 你的问题是什么? (请注意,这会产生高 CPU 使用率)
  • 如果秒表以毫秒为单位,这意味着每秒更新 1,000 次。即使使用计时器,更新用户界面也需要很多次。
  • 我已将该代码放入mainWindow(){}。但是表单在定时器到了 3000 毫秒后才开始,所以表单在定时器停止后才开始。
  • @Victor Barbu- 你不能从窗口构造函数中真正更新 GUI,因为在构造函数完成之前窗口是不可见的。

标签: c# timer stopwatch


【解决方案1】:

你最好使用System.Windows.Forms.Timer,而不是Stopwatch()

即使该计时器的准确度低于StopWatch(..),它也可以为您提供良好的控制。

只是示例片段:

   myTimer.Tick += new EventHandler(TimerEventProcessor);       
   myTimer.Interval = 1350;
   myTimer.Start();

   private void TimerEventProcessor(...){          
     label1.Text = "...";
   }

【讨论】:

  • 虽然,我猜他在做label1.Text = ..之前需要检查InvokeRequired,对吧..?
  • @Default: 否,如果您不需要 Windows.Forms.Timer,它会在 UI 线程上运行。 System.Timer.Timer 在其他线程上运行,所以那里是的,你需要管理 Invoke 的东西。
【解决方案2】:

您不能像这样在一个紧密的循环中更新 UI,因为当 UI 线程运行该代码时,它没有响应绘制事件。你可以做一些讨厌的事情,比如“DoEvents()”,但请不要……最好只有一个Timer,并在定时器事件触发时定期更新 UI;就我个人而言,每 50 毫秒绝对是最快的。

【讨论】:

    【解决方案3】:

    这是一个 WinForms 应用程序吗?

    问题在于,当您的循环运行时,它不会给任何其他任务(如更新 GUI)提供任何完成的可能性,因此 GUI 将更新整个循环完成。

    您可以在此处添加快速且“肮脏”的解决方案(如果是 WinForms)。像这样修改你的循环:

    while (timer.ElapsedMilliseconds < 3000) {
      label1.Text = Convert.ToString( timer.ElapsedMilliseconds );
      Application.DoEvents();
    }
    

    现在标签应该在循环运行之间更新。

    【讨论】:

    • 是的,它有效,但我希望这只是为了测试目的。我不会在任何实际应用程序中依赖紧密循环和 Application.DoEvents()。这是一种黑客行为;)
    • 当然只是为了学习。我找到了所有关于System.Windows.Forms.Timer
    【解决方案4】:

    如果您希望它每秒更新一次,您可以在 while 循环中使用模运算符:

    Stopwatch timer = new Stopwatch();
    
    timer.Start();
    
    while (timer.ElapsedMilliseconds < 3000) {
        if (timer.ElapsedMilliseconds % 1000 == 0)
        {
            label1.Text = timer.ElapsedMilliseconds.ToString();
        }
    }
    
    timer.Stop();
    

    模运算符给出除法运算的余数,如果毫秒是 1,000 的倍数,它将返回 0。

    我可能会考虑使用Timers。您使用上述技术做了很多旋转,这可能会导致您的 UI 无响应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-06
      • 2011-05-27
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多