1

I have tried Dispatcher timer but it doesn't seem to be working correctly.

I have the tick event set up that adds to a tick counter every tick and it's just not doing the job right. I also have a Stopwatch to count how long it's been, and the numbers aren't matching up. Please let me know what kind of solution would work to give me 192 ticks each second.

    Stopwatch sw = new Stopwatch();
    public DispatcherTimer dt = new DispatcherTimer();
    dt.Tick += dt_Tick;
    dt.Interval = TimeSpan.FromMilliseconds(1000/192);
    dt.Start();
    sw.Start();

void dt_Tick(object sender, EventArgs e)
{
    tick_textbox.Text = tick_counter.ToString();
    seconds_textbox.Text = sw.Elapsed.ToString();
    tick_counter++;
}

Now, I've lowered it to 8 per second, which should solve the resolution problem, but I'm getting wildly different outcomes from using an interval of TimeSpan.FromSeconds and TimeSpan.FromMilliseconds:

    dt.Tick += dt_Tick;
    dt.Interval = TimeSpan.FromSeconds(2 / 16);
    dt.Start();

vs.

    dt.Tick += dt_Tick;
    dt.Interval = TimeSpan.FromMilliseconds(2000 / 16);
    dt.Start();

What is the reason for that?

marseilles84
  • 396
  • 2
  • 7
  • 21
  • 4
    Is the requirement just that the event is fired 192 times per second, or that the event is fired once every 1/192 second? If the former, then you could just keep track of the start time of each 1 second interval, and fire the events as fast as you can until you have fired 192. Then stop until the next 1 second interval begins. – mbeckish May 16 '13 at 17:28
  • 1000 is not divisible by 192. The closest you can get (and what you're currently doing) is 200 times per second. The only ways to (theoretically) accomplish this are to skip ticks or use a variable interval. Even then, the timers aren't accurate at this resolution. – JosephHirn May 16 '13 at 17:42
  • 3
    **Windows is not a realtime operating system.** It's a general-purpose business application operating system. Use the right tool for the job; if you need something to happen precisely 192 times a second, get yourself an operating system that was designed with that sort of task in mind. – Eric Lippert May 16 '13 at 18:29
  • 3
    2 / 16 is 0, 2.0 / 16 is 0.125 – IngisKahn May 16 '13 at 18:39

1 Answers1

8

You're asking for an event every 5ms and the .NET timers are simply not reliable at this resolution

http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=815

From the article:

The conclusion I drew from all my testing is that, at best, you can count on a timer to tick within 15 milliseconds of its target time. It's rare for the timer to tick before its target time, and I never saw it be early by more than one millisecond. The worst case appears to be that the timer will tick within 30 milliseconds of the target time. Figure the worst case by taking your desired target frequency (i.e. once every 100 milliseconds), rounding up to the next multiple of 15, and then adding 15. So, absent very heavy CPU load that prevents normal processing, a 100 ms timer will tick once every 99 to 120 ms.

You definitely can't get better resolution than 15 milliseconds using these timers. If you want something to happen more frequently than that, you have to find a different notification mechanism. No .NET timer object will do it.

There are ways to get this resolution but they typically involve specific hardware designed for high-frequency timing applications and driver interop for their events. I've done this before using an acousto-optic modulator, laser source and CCD.

Community
  • 1
  • 1
Matthew
  • 10,244
  • 5
  • 49
  • 104