我需要在我的应用程序中使用高分辨率(比1毫秒更准确)的计时。Windows中的可等待定时器可以(或可以被制成)精确到毫秒,但如果我需要精确的周期性,例如35.7142857141毫秒,即使具有36毫秒周期的可等待定时器也会很快失去同步。
我对这个问题的“解决方案”(用引号括起来是因为它并不完全正确)是使用一系列单次定时器,其中我使用每个定时器的到期来调用下一个定时器。通常,这样的过程会随着时间的推移而累积误差,但在每个定时器回调中,我检查当前时间(使用System.Diagnostics.Stopwatch),并使用它来计算下一个定时器的周期(因此,如果定时器稍微延迟到期,下一个定时器将自动缩短周期以进行补偿)。
这正如预期的那样工作,但是大约10-15秒后,定时器系统似乎变得阻塞,并且有些定时器回调偶尔会晚到25到100毫秒。几秒钟后,问题就消失了,一切都再次顺利地运行了10-15秒,然后又出现了口吃。
由于我正在使用Stopwatch设置每个计时器周期,因此我也在使用它来监视每个计时器回调的到达时间。在平稳运行的期间,大多数(可能95%)的间隔为35或36毫秒,并且没有任何间隔距离预期的35.7142857143超过5毫秒。
在“口吃”的阶段,间隔的分布非常接近,但有很少量的间隔异常大(在大约3秒的时间内,有几个间隔大于60毫秒和一两个间隔长于100毫秒)。这种口吃非常明显,如果可能,我正在尝试修复它。
对于高分辨率计时器,我使用了极古老的timeSetEvent()多媒体计时器从winmm.dll中获取。在解决这个问题时,我切换到使用CreateTimerQueueTimer(以及timeBeginPeriod设置高分辨率),但是我在两种计时器机制中都遇到了同样的问题。我尝试使用CreateTimerQueueTimer的各种标志进行实验,以确定计时器运行的线程,但无论如何,口吃都会出现。
这只是使用定时器的基本问题吗(即使用每个单次定时器调用下一个)?如果是这样,我还有其他选择吗?我正在考虑的一件事是确定在需要重置计时器之前,连续多少个1毫秒精度的滴答声会使我保持在某些任意精度限制内。因此,例如,如果我想要35.71428周期,我可以让36毫秒计时器过去15次,然后它就会偏离5毫秒,然后杀死它并启动一个新的计时器。
我对这个问题的“解决方案”(用引号括起来是因为它并不完全正确)是使用一系列单次定时器,其中我使用每个定时器的到期来调用下一个定时器。通常,这样的过程会随着时间的推移而累积误差,但在每个定时器回调中,我检查当前时间(使用System.Diagnostics.Stopwatch),并使用它来计算下一个定时器的周期(因此,如果定时器稍微延迟到期,下一个定时器将自动缩短周期以进行补偿)。
这正如预期的那样工作,但是大约10-15秒后,定时器系统似乎变得阻塞,并且有些定时器回调偶尔会晚到25到100毫秒。几秒钟后,问题就消失了,一切都再次顺利地运行了10-15秒,然后又出现了口吃。
由于我正在使用Stopwatch设置每个计时器周期,因此我也在使用它来监视每个计时器回调的到达时间。在平稳运行的期间,大多数(可能95%)的间隔为35或36毫秒,并且没有任何间隔距离预期的35.7142857143超过5毫秒。
在“口吃”的阶段,间隔的分布非常接近,但有很少量的间隔异常大(在大约3秒的时间内,有几个间隔大于60毫秒和一两个间隔长于100毫秒)。这种口吃非常明显,如果可能,我正在尝试修复它。
对于高分辨率计时器,我使用了极古老的timeSetEvent()多媒体计时器从winmm.dll中获取。在解决这个问题时,我切换到使用CreateTimerQueueTimer(以及timeBeginPeriod设置高分辨率),但是我在两种计时器机制中都遇到了同样的问题。我尝试使用CreateTimerQueueTimer的各种标志进行实验,以确定计时器运行的线程,但无论如何,口吃都会出现。
这只是使用定时器的基本问题吗(即使用每个单次定时器调用下一个)?如果是这样,我还有其他选择吗?我正在考虑的一件事是确定在需要重置计时器之前,连续多少个1毫秒精度的滴答声会使我保持在某些任意精度限制内。因此,例如,如果我想要35.71428周期,我可以让36毫秒计时器过去15次,然后它就会偏离5毫秒,然后杀死它并启动一个新的计时器。