Tuesday, March 1, 2011

Accurate Windows timer? System.Timers.Timer() is limited to 15 msec.

I need an accurate timer to interface a Windows application to a piece of lab equipment.

I used System.Timers.Timer() to create a timer that ticks every 10 msec, but this clock runs slow. For example 1000 ticks with an interval of 10 msec should take 10 wall-clock seconds, but it actually takes more like 20 wall-clock sec (on my PC). I am guessing this is because System.Timers.Timer() is an interval timer that is reset every time it elapses. Since it will always take some time between when the timer elapses and when it is reset (to another 10msec) the clock will run slow. This probably fine if the interval is large (seconds or minutes) but unacceptable for very short intervals.

Is there a function on Windows that will trigger a procedure every time the system clock crosses a 10 msec (or whatever) boundary?

This is a simple console application.

Thanks

Norm

UPDATE: System.Timers.Timer() is extremely inaccurate for small intervals.

I wrote a simple program that counted 10 seconds several ways:

Interval=1, Count=10000, Run time = 160 sec, msec per interval=16

Interval=10, Count=1000, Run time = 16 sec, msec per interval=15

Interval=100, Count=100, Run time = 11 sec, msec per interval=110

Interval=1000, Count=10, Run time = 10 sec, msec per interval=1000

It seems like System.Timers.Timer() cannot tick faster that about 15 msec, regardless of the interval setting.

Note that none of these tests seemed to use any measurable CPU time, so the limit is not the CPU, just a .net limitation (bug?)

For now I think I can live with an inaccurate timer that triggers a routine every 15 msec or so and the routine gets an accurate system time. Kinda strange, but...

I also found a shareware product ZylTimer.NET that claims to be a much more accurate .net timer (resolution of 1-2 msec). This may be what I need. If there is one product there are likely others.

Thanks again.

From stackoverflow
  • You need to use a high resolution timer such as QueryPerformanceCounter

    Patrick Cuff : There's also a nice write up at the MSDN: Implement a Continuously Updating, High-Resolution Time Provider for Windows (http://msdn.microsoft.com/en-us/magazine/cc163996.aspx)
    AnthonyWJones : As of .NET 2.0 a high res stop watch is already available (assuming the OS supports it). However that isn't all that useful in this scenario. The second like might be.
    AnthonyWJones : @Patrick: your link may be headed in the right direction, perhaps the answer is there, in which case it needs to included as answer.
  • On surface of it the answer is something like "high resolution timer" however this is incorrect. The answer requires a regular tick generation and the windows high res performance counter API does not generate such a tick.

    I know this is not answer inself but the popular answer to this question so far is wrong enough for me to feel that a simple comment on it is not enough.

    Ahmed Said : what is the meaning of "a regular tick generation "?
    AnthonyWJones : @Ahmed: creating some kind of event with a periodic interval, a clock signal. The question was asking for accurate deliver of such events. The top answer here is wrong, its not possible to deliver such a thing in a non-determistic OS such as windows.
  • In System.Diagnostics, you can use the Stopwatch class.

  • Off the top of my head, I could suggest running a thread that mostly sleeps, but when it wakes, it checks a running QueryPerformanceCounter and occasionally triggers your procedure.

    AnthonyWJones : Again determinism is a factor here, the question really needs a clear specification of period and tolerance to be able to determine whether if any this solution would work.
  • There's a nice write up at the MSDN: Implement a Continuously Updating, High-Resolution Time Provider for Windows

    Here's the sample source code for the article (C++).

0 comments:

Post a Comment