【问题标题】:Internal of .NET timer controller.NET 定时器控制器的内部
【发布时间】:2017-03-16 06:23:33
【问题描述】:

在 VB.NET 或 C# 中,Windows 窗体应用程序可以添加一个计时器控制器以按计划方式运行任务。但是定时器的内部实现是什么?它是否为每个计时器使用单独的线程?还是线程池?还是其他并发编程范式?

编辑

另外,我想知道定时器控制器是否满足如下所述的并发安全属性?

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    i = i + 1 //Line 1
              //Line 2, some code is here will takes some cpu time
    i = i - 1 //Line 3
              //Line 4, some code is here; takes another cpu time
End Sub

我们能否保证公共变量 i 始终具有值 1 或 0?

【问题讨论】:

  • 定时器有很多种,你指的是哪一种?为什么不检查reference code
  • @LeiYang 将此作为答案发布。这是我所期望的(参考代码)。
  • 如果您想查看实现,请转到the source

标签: c# .net vb.net winforms


【解决方案1】:

Windows 窗体计时器 (System.Windows.Forms.Timer) 将在 UI 线程上运行(它将计时器事件发布到主事件循环)。

System.Timers.Timer 默认使用线程池处理定时器事件。

回答您更新的问题:假设您使用的是System.Windows.Forms.Timer,滴答处理程序将始终在运行下一个滴答事件之前运行完成(因为它们始终在同一线程上运行)。不过不要忘记包含在 try/finally 中。

【讨论】:

  • "不要忘记在 try/finally 中换行。" - 为什么?
【解决方案2】:

来自MSDN:“计时器用于以用户定义的时间间隔引发事件。此 Windows 计时器专为使用 UI 线程执行处理的单线程环境而设计。它要求用户代码有一个可用的 UI 消息泵,并且总是从同一个线程操作,或者将调用编组到另一个线程。” (强调我的)

所以它与您的应用程序在同一个线程中运行,并且它以某种方式让 Windows 消息泵定期引发其 Tick 事件。如果Tick 事件中的代码需要一段时间才能运行,那么您的应用在完成之前不会更新其 UI。在长时间运行的Tick 事件期间使用DoEvents 让UI 更新可能会让自己陷入各种麻烦,但我建议改用BackgroundWorker - 编码有点困难,但是更容易做到正确。

【讨论】:

  • 请注意,.NET 中有不止一个 Timer 类。只有 Windows 窗体计时器由主事件循环驱动。
  • 原来的问题具体提到了windows forms“timer controller”。
猜你喜欢
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 2011-11-23
  • 2023-04-10
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多