与 System.Windows.Forms.Timer 的间隔不一致 [英] Inconsistent intervals with System.Windows.Forms.Timer

查看:44
本文介绍了与 System.Windows.Forms.Timer 的间隔不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请善待,我只是在学习 C#,从前雇员那里继承这个应用程序是我的第一个 C# 项目.

Please be kind, I'm just learning C# and inheriting this application from a former-employee is my first C# project.

我观察到 System.Windows.Forms.Timer 出现不一致和缓慢的时期.该应用程序是用 C# 和 MS Visual Studio 编写的.

I am observing inconsistent and slow periods with System.Windows.Forms.Timer. The application is written in C# with MS Visual Studio.

计时器的间隔设置为 100 毫秒,但我观察到的周期为 110 毫秒到 180 毫秒.

The timer is set for an interval of 100 msec yet I am observing periods ranging from 110 msec to 180 msec.

我正在使用多种工具来观察这一点,包括:- 一个软件示波器(Iocomp.Instrumentation.Plotting.Plot 包),- 真正的示波器,- 让计时器运行一段时间并将滴答数 * 100 毫秒与系统时间和秒表进行比较.

I am using several tools to observe this including: - a SW oscilloscope (the Iocomp.Instrumentation.Plotting.Plot package), - a real oscilloscope, - letting the timer run for some time and comparing the number of ticks * 100 msec to both the system time and to a stopwatch.

在所有情况下,我都观察到 10% 的延迟,这在前几秒内变得明显.

In all cases I am observing a 10% lag that becomes evident within the first few seconds.

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

The methods that are executed with each tick take fewer than 4 msec to run. There is no time-consuming asynchronous processing happening, either. This shouldn't matter, though, as the timer tick is an interrupt, not an event added to an event handler queue (as far as I know).

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

Has anyone experienced a problem like this before? What were the root causes?

谢谢.

推荐答案

计时器的准确度仅与操作系统时钟中断一样准确.默认情况下,每秒滴答 64 次,即 15.625 毫秒.你不能从中得到一个干净的 100 毫秒间隔,它不能被 15.625 整除.你得到下一个整数倍,7 x 15.625 = 109.375 毫秒.非常接近您观察到的 110 毫秒.

Timers are only as accurate as the operating system clock interrupt. Which ticks 64 times per second by default, 15.625 msec. You cannot get a clean 100 msec interval from that, it isn't divisible by 15.625. You get the next integer multiple, 7 x 15.625 = 109.375 msec. Very close to the 110 msec you observed.

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

You need to add the latency in the handling of the timer notification to this theoretical minimum. Timers have to compete with everything else that's going on in your UI thread. They are treated as the least important notification to be delivered. Sent messages go first, user input goes next, painting is next, timer messages are last. Either way, if you have an elaborate user interface that takes a while to repaint then the Tick event is going to be delayed until that's done. Same for any event handler you write that does something non-trivial like reading a file or querying a dbase.

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

To get a more responsive timer that doesn't suffer from this kind of latency, you need to use an asynchronous timer. System.Threading.Timer or System.Timers.Timer. Avoid the latter. Their callback runs on a threadpool thread so can get running pretty quickly. Be very careful what you do in this callback, lots of things you cannot do because they are not thread-safe.

您可以通过更改时钟中断率来使这些计时器更准确.这需要 pinvoke,调用 timeBeginPeriod().timeEndPeriod() 完成后.

You can these timers more accurate by changing the clock interrupt rate. That requires pinvoke, call timeBeginPeriod(). timeEndPeriod() when you're done.

这篇关于与 System.Windows.Forms.Timer 的间隔不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆