了解C#中Timer控件的工作原理

假设我有一个定时器控件,间隔设置为20ms。 在这个控件里面,我正在做一些需要100ms才能完成的操作。 因此,一旦它执行该操作,Timer控件是否会再次执行而无需等待该操作完成? 或者直到该操作没有完成,Timer才会再次执行?

编辑
我在控制台应用程序的单独线程中使用System.Timers.Timer()。 我在下面与安德鲁讨论后编辑了我的问题。

System.Timers.Timer在“随机”线程池线程上运行并引发事件。 回调和计时器滴答将同时运行,这意味着在间隔小于方法终止所用时间的情况下,您将重叠执行这些事件。

即使这种行为与我在下面发布的行为不同,您仍然不想这样做。 结果将是线程池最终将耗尽。 它也可能不是您想要的function。

解决方案是对其进行编码,使得无法进行并发执行。

  1. 测试一些静态字段以查看现有迭代是否正在运行,如果是,则取消“新”实例。 测试/设置这样的字段应该通过内存屏障来完成。
  2. 进入事件后停止计时器,运行代码,然后再次启动。 如果您愿意,可以根据执行时间来调整间隔。
  3. 在完成之前的操作之前,不要进行简单的锁定来阻止并发执行; 这将回到我用Windows窗体定时器描述的问题(减去UI锁定)

上一个答案

当我以为你在System.Windows.Forms中谈到Timer并在Windows Forms程序中使用它时,这是我发布的旧答案。 因为情况并非如此,以下信息不适用于您。 但我把它留在这里,以防它帮助其他人。

因为System.Windows.Forms命名空间内的Timer控件在UI线程上运行,其回调也是如此,您的tick事件将堆积起来,等待当前正在执行的操作完成。 您的UI也将在持续时间内被锁定。

因此,您希望这样做。 你的程序会锁定。

System.Windows.Forms.Timer是单线程的,只有55ms的分辨率。但由于它是单线程的,因此Tick事件不应该相互衔接。

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

在单线程应用程序中,如果执行不可能,则滴答将排队。 它还具有~55ms的分辨率

请参阅http://msdn.microsoft.com/en-us/library/xdh6857z.aspx

请参见如何防止System.Timers.Timer在线程池上排队执行?

System.Timers.Timer

.NET Framework文档将System.Timers.Timer类称为基于服务器的计时器,该计时器是为在multithreading环境中使用而设计和优化的。 可以从多个线程安全地访问此计时器类的实例。 与System.Windows.Forms.Timer不同,System.Timers.Timer类默认情况下将调用从公共语言运行时(CLR)线程池获取的工作线程上的计时器事件处理程序。

有关计时器类型的更多详细信息,请参阅链接http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

注意:前面的示例是在假定计时器实例是System.Windows.Forms.Timer的情况下编写的,但作者的说明表明使用了System.Timers.Timer()实例。