【问题标题】:System.Windows.Forms.Timer is NOT Firing Tick Event Inside Foreach BlockSystem.Windows.Forms.Timer 不会在 Foreach 块内触发 Tick 事件
【发布时间】:2014-02-28 16:31:44
【问题描述】:

我有一个与我的主窗体关联的 System.Windows.Forms.Timer。我需要这个计时器每 1000 毫秒触发一次,以便可以执行一些工作。 Timer.Enabled 属性在 Form.Shown 事件中设置为 true,间隔设置为 1000。

Timer.Tick 事件在大多数情况下大约每秒触发一次。但是,当我的应用程序执行 foreach 语句时,Tick 事件会停止触发。我试过 Thread.Sleep ,但是没有帮助。有没有人有什么建议?处理我的 Timer.Tick 事件的代码包含异常处理,并且我已验证在执行 foreach 块期间该事件在调试器中停止触发。此外,我的应用程序此时不是多线程的。有什么建议吗?

【问题讨论】:

  • 请发布代码。
  • 如果您在循环中保持 UI 线程忙碌,那么不,计时器 Tick 处理程序将无法执行。如果您有一个长时间运行的循环,请将其推送到后台线程。 Sleep 无济于事,因为这也会阻塞 UI 线程。还有其他计时器不会在 UI 线程 (System.Timer) 上触发,但如果您的 tick 需要访问 UI,那么如果 UI 线程仍然很忙,这实际上对您没有帮助。
  • 现在多线程你的应用程序...
  • 谢谢,我会重新考虑使用后台线程。我知道我可能在做一些愚蠢的事情。如果您发布您的答案 Matt Burland,我会在稍后接受答案。
  • Application.DoEvents 在你的循环中会有所帮助,但它是一个廉价的修复。您可以在另一个线程中执行循环,因为它当前正在阻止 UI 线程执行,而这正是发生滴答事件的地方。后台工作人员可以帮助您做到这一点:msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

标签: c# winforms timer


【解决方案1】:

如果您在循环中保持 UI 线程忙碌,那么不,计时器 Tick 处理程序将无法执行。如果您有一个长时间运行的循环,请将其推送到后台线程。睡眠无济于事,因为这也会阻塞 UI 线程。还有其他计时器不会在 UI 线程 (System.Timer) 上触发,但如果您的 tick 需要访问 UI,那么如果 UI 线程仍然很忙,这实际上对您没有帮助。

【讨论】:

  • 这为我指明了正确的方向,但我不得不使用 System.Threading.Timer 因为 System.Timer 有时仍然没有触发 Elapsed 事件
【解决方案2】:

System.Timers.Timer 的实现可能如下所示:

var timer = new System.Timers.Timer();
timer.Interval = 1000; // every second
timer.Elapsed += TimerTick;

...

private void TimerTick(object state, System.Timers.ElapsedEventArgs e)
{
    // do some work here
    Thread.Sleep(500);

    var reportProgress = new Action(() => 
    {  
        // inside this anonymous delegate, we can do all the UI updates
        label1.Text += string.Format("Work done {0}\n", DateTime.Now);
    });
    Invoke(reportProgress);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    相关资源
    最近更新 更多