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

标签 c# timer period frequency-analysis

请客气,我刚刚学习 C#,从前雇员那里继承这个应用程序是我的第一个 C# 项目。

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

计时器设置为 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 事件将被延迟直到重新绘制完成。对于您编写的任何事件处理程序都一样,它会执行一些重要的事情,例如读取文件或查询数据库。

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

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

关于c# - 与 System.Windows.Forms.Timer 的间隔不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25876342/

相关文章:

c# - 推荐XNA教程开始学习3D(第一次)

java - 更改操作系统日期和时间后线程 hibernate

c# - System.Threading.Timer.Timer() 的最佳重载方法匹配有一些无效参数

Java:为什么 java.LocalDate 格式在 2018-10-25 到 2019-10-25 之间给出 0 天?

c# - 定期从内存流播放音频 C#

c# - NServiceBus - 基于内容的路由和审计 - 我的方法可以吗?

javascript - 使用 SPA 对 Microsoft Graph 进行身份验证,然后在 Web API 中使用 token

ios - 后台任务不会在 Swift 中重新启动

一段时期内每天的 Twig 日期循环