Problem with expected timers on Windows (timeSetEvent and CreateTimerQueueTimer)

I need to have a high resolution (more accurate than 1 millisecond) in my application. Expected timers on Windows (or can be made) are accurate to milliseconds, but if I need an exact frequency of, say, 35.7142857141 milliseconds, even an expected timer with a period of 36 ms will quickly go out of sync.

My "solution" to this problem (in ironic quotes, because it does not work correctly) is to use a series of one-time timers, where I use the expiration of each timer to call the next timer. Normally, a process like this would experience a cumulative error over time, but in each timer callback I check the current time (with System.Diagnostics.Stopwatch) and use it to calculate what time period should be for the next timer (so if the timer happens, expires a little late, the next timer will automatically have a shorter period for compensation).

This works as expected, except that after 10-15 seconds the timer system seems to get bogged down, and several timer callbacks here and there arrive anywhere from 25 to 100 milliseconds. After a couple of seconds, the problem will disappear, and everything will go smoothly again within 10-15 seconds, and then stutters again.

Since I use Stopwatchto set each timer period, I also use it to track the arrival time of each timer callback. During periods of smooth operation, most (perhaps 95%) of the intervals are 35 or 36 milliseconds, and no intervals exceed 5 milliseconds from the expected 35.7142857143.

During โ€œconvulsiveโ€ stretchings, the distribution of the intervals is almost the same, except that a very small number is unusually large (a pair of more than 60 ms and one or two longer than 100 ms, during a possibly 3-second stretch). This stutter is very noticeable, and this is what I'm trying to fix, if possible.

For the high resolution timer, I used an extremely antique timeSetEvent()multimedia timer from winmm.dll. To solve this problem, I switched to using CreateTimerQueueTimer(along with timeBeginPeriodto set a high resolution), but I see the same problem with both timer mechanisms. I tried experimenting with various flags for CreateTimerQueueTimerthat determine which thread the timer is running on, but stuttering appears no matter what.

(.. )? , - ? , , , , 1 , reset . , , 35.71428, 36 15 , 5 , .

+3
2

.NET, , . ? , , , , .

, .NET . , , ..

? , - . , , Windows CE , .

+3

1 , 35,7, . , , .
(35 36) .

, , .NET framework - . , GC ?

+1

Source: https://habr.com/ru/post/1738493/


All Articles