与System.Windows.Forms.Timer不一致的间隔

请善待,我只是学习C#并从前员工inheritance这个应用程序是我的第一个C#项目。

我正在使用System.Windows.Forms.Timer观察不一致和缓慢的时期。 该应用程序使用MS Visual Studio以C#编写。

定时器设置为100毫秒的间隔,但我观察的时间范围是110毫秒到180毫秒。

我正在使用几种工具来观察这一点,包括: – 一个SW示波器(Iocomp.Instrumentation.Plotting.Plot包), – 一个真实的示波器, – 让定时器运行一段时间,并将滴答数* 100毫秒与两者相比较系统时间和秒表。

在所有情况下,我观​​察到在最初几秒内变得明显的10%滞后。

每次滴答执行的方法运行时间不到4毫秒。 也没有耗时的异步处理。 但这应该无关紧要,因为计时器滴答是一个中断,而不是添加到事件处理程序队列的事件(据我所知)。

以前有没有人遇到这样的问题? 根本原因是什么?

谢谢。

定时器仅与操作系统时钟中断一样准确。 默认为每秒64次,15.625毫秒。 你不能从那里获得一个干净的100毫秒间隔,它不能被15.625整除。 你得到下一个整数倍,7 x 15.625 = 109.375毫秒。 非常接近你观察到的110毫秒。

您需要将处理定时器通知的延迟添加到此理论最小值。 计时器必须与UI线程中正在发生的所有其他事件竞争。 它们被视为不重要的通知。 首先发送消息,接下来是用户输入,接下来是绘画,定时消息是最后一个。 无论哪种方式,如果你有一个精心设计的用户界面需要一段时间来重新绘制,那么Tick事件将会延迟,直到完成。 对于您编写的任何事件处理程序也是如此,它可以执行诸如读取文件或查询dbase等非常重要的事情。

要获得不会受到此类延迟影响的响应更快的计时器,您需要使用异步计时器。 System.Threading.Timer或System.Timers.Timer。 避免后者。 它们的回调在线程池线程上运行,因此可以很快运行。 你要非常小心你在这个回调中所做的事情,很多事情你不能做,因为它们不是线程安全的。

通过改变时钟中断率,您可以更准确地定位这些定时器。 这需要pinvoke,调用timeBeginPeriod()。 完成后的timeEndPeriod()。

是的,我总是遇到System.Windows.Forms.Timer这个问题,因为它没有准确(大多数时候)。 您可以尝试使用System.Timers.Timer ,它可以精确地引发中断(至少100ms精度)

System.Windows.Forms.Timer实际上只是本机WM_TIMER消息的包装器。 这意味着计时器消息在大致接近您请求的时间间隔时放置在消息队列中(加或减……这里不保证)。 何时处理该消息完全依赖于队列中的其他消息以及每个消息处理的时间。 例如,如果阻止UI线程(从而阻止队列处理新消息),则在解除阻塞之前不会获得计时器事件。

Windows不是一个实时操作系统,你不能指望定时器的细粒度准确性。 如果您想要更细粒度的东西,多媒体计时器是最佳选择。

这是旧的,但如果有人来这里寻找一个真正正确的答案:

来自https://msdn.microsoft.com/en-us/library/system.windows.forms.timer ( v= vs.110) .aspx (强调我的):

Windows窗体计时器组件是单线程的, 精度限制为55毫秒 。 如果需要更高精度的multithreading计时器,请使用System.Timers命名空间中的Timer类。

因此,使用Windows.Forms.Timer,您可以获得55ms,110ms,165ms等; 这与你所看到的一致。 如果需要更高的精度,请尝试System.Timers.TimerSystem.Threading.Timer