- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的应用程序需要高分辨率(比 1 毫秒更准确)计时。 Windows 中的可等待计时器精确到(或可以精确到毫秒),但如果我需要精确的周期,比如 35.7142857141 毫秒,即使是 36 毫秒周期的可等待计时器也会很快失去同步。
我对这个问题的“解决方案”(具有讽刺意味的是,因为它不能正常工作)是使用一系列一次性计时器,我使用每个计时器的到期时间来调用下一个计时器。通常这样的过程会随着时间的推移出现累积误差,但在每个计时器回调中我检查当前时间(使用 System.Diagnostics.Stopwatch
)并使用它来计算下一个时间段计时器需要(所以如果一个计时器碰巧过期晚了一点,下一个计时器将自动有一个更短的周期来补偿)。
这按预期工作,只是在大约 10-15 秒后计时器系统似乎陷入停滞,并且这里和那里的一些计时器回调到达任何地方从 25 到 100 毫秒不等。几秒钟后,问题消失,10 到 15 秒内一切再次平稳运行,然后再次卡顿。
因为我使用 Stopwatch
来设置每个计时器周期,所以我也用它来监视每个计时器回调的到达时间。在平稳运行期间,大部分(可能是 95%)的间隔为 35 或 36 毫秒,并且没有任何间隔与预期的 35.7142857143 相差超过 5 毫秒。
在“故障”拉伸(stretch)期间,间隔的分布几乎相同,除了非常小的数字异常大(一对超过 60 毫秒,一两个超过 100 毫秒,可能在 3 秒的拉伸(stretch)中).这种卡顿非常明显,如果可能的话,这是我正在努力解决的问题。
对于高分辨率计时器,我使用了 winmm.dll
中非常古老的 timeSetEvent()
多媒体计时器。为了解决这个问题,我转而使用 CreateTimerQueueTimer
(连同 timeBeginPeriod
来设置高分辨率),但我发现两种计时器机制都存在同样的问题。我已经尝试使用 CreateTimerQueueTimer
的各种标志进行试验,这些标志确定计时器在哪个线程上运行,但无论如何都会出现卡顿现象。
这只是以这种方式使用计时器的一个基本问题吗(即使用每个一次性计时器调用下一个计时器)?如果是这样,我还有其他选择吗?我正在考虑的一件事是确定在我需要重置计时器之前有多少个连续的 1 毫秒精度滴答声可以使我的精度保持在某个任意精度限制内。因此,例如,如果我想要一个 35.71428 周期,我可以让一个 36 毫秒计时器在它关闭 5 毫秒之前经过 15 次,然后终止它并启动一个新计时器。
最佳答案
考虑到 .NET 的局限性,我认为您有一个很好的方法。您的流程优先级是什么?我认为它需要高于正常值以避免其他进程进行磁盘事件。
我同意 Henk 的观点,即 .NET 框架不是这里的最佳解决方案。如果发生垃圾收集,可能需要一段时间来释放对象、压缩堆等。
您使用的是什么操作系统?我也同意 Henk 的观点,实时操作系统是最好的解决方案。根据我读到的内容,Windows CE 有资格作为实时操作系统,但我真的不能进一步评论。
关于c# - Windows 中可等待计时器的问题(timeSetEvent 和 CreateTimerQueueTimer),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2515975/
我的应用程序需要高分辨率(比 1 毫秒更准确)计时。 Windows 中的可等待计时器精确到(或可以精确到毫秒),但如果我需要精确的周期,比如 35.7142857141 毫秒,即使是 36 毫秒周期
我是一名优秀的程序员,十分优秀!