4

I'm using a DispatcherTimer to call a void in C#:

        counter = new System.Windows.Threading.DispatcherTimer();
        counter.Tick += new EventHandler(counter_Tick);
        counter.Interval = new TimeSpan(0, 0, 1);
        counter.Start();

However I would like the interval to be a few milliseconds, TimeSpan's parameters are hours,minutes,seconds and only accepts integers (as far as I can see). Is there a work around for DispatcherTimer? I've tried Timer but I cannot use it (missing reference apparently)

Thanks in advance.

rageit
  • 3,513
  • 1
  • 26
  • 38
user1785715
  • 180
  • 1
  • 1
  • 8
  • 1
    `TimeSpan` has a constructor that takes milliseconds: [see MSDN](https://msdn.microsoft.com/en-us/library/6c7z43tw(v=vs.110).aspx). Basically, use `new TimeSpan(0, 0, 0, 0, milliseconds);` – Der Kommissar Jun 01 '15 at 19:35
  • @EBrown definitely post this as an aswer I think – Pseudonym Jun 01 '15 at 19:38

3 Answers3

9

Another way

  counter.Interval = TimeSpan.FromMilliseconds(1);
Null Pointer
  • 9,089
  • 26
  • 73
  • 118
7

The TimeSpan object has a constructor that takes milliseconds as a parameter:

MSDN has the details: https://msdn.microsoft.com/en-us/library/6c7z43tw(v=vs.110).aspx

Basically, replace new TimeSpan(0, 0, 1) with new TimeSpan(0, 0, 0, 0, millisecondTimeout).

Der Kommissar
  • 5,848
  • 1
  • 29
  • 43
2

Although @EBrown's answer already tells you how to use milliseconds with a DispatcherTimer, its precision is supposedly around 15-20 ms, and the errors add up at each iteration, which makes it a bit impractical.

However it is possible to work around this issue by starting a System.Diagnostics.StopWatch at the same time as the DispatcherTimer and checking the StopWatch.ElapsedMilliseconds inside the Tick Event with a smaller time step, and that seems to give more precise results. It also works with a System.Timers.Timer.

Here's a short example based on a WPF program I made.

private void StartTimers(object sender, RoutedEventArgs e)
{
    dtimer = new DispatcherTimer();
    dtimer.Tick += new EventHandler(dTimer_Tick);
    dtimer.Interval = TimeSpan.FromMilliseconds(1);  // the small time step

    stopWatch = new StopWatch();

    dTimer.Start();
    stopWatch.Start();
}

private void dTimer_Tick(object sender, EventArgs e)
{        
     currentTime = stopWatch.ElapsedMilliseconds;
        if (currentTime - oldTime > interval)
        {
            oldTime = currentTime;
            DoStuff();
        }
}   

Using StopWatch.Restart in the Tick Event to do iterations will have the same error problem the DispatchTimer causes, because it's going to restart when the DispatchTimer event is fired.