Getting Elapsed Time with DispatchTimer to 1 millisecond accuracy

James Santiago picture James Santiago · Nov 23, 2010 · Viewed 10.8k times · Source

I'm trying to measure the elapsed time in milliseconds between keypress events using a dispatch timer but when declaring a dispatch timer to have an interval of 1 millisecond and then establishing the tick event it doesn't fire every 1 millisecond but somewhere like 10-100 milliseconds (guess). How do I accurately measure time in milliseconds if this tick event doesn't fire on time? I'm doing this in silverlight which doesn't seem to have access to System.Timers. The same seems to happen with System.Threading.Timer.

Here's the basics of the code:

public void StartTimer(object o, RoutedEventArgs sender)
{
    System.Windows.Threading.DispatcherTimer myDispatcherTimer = new  
    System.Windows.Threading.DispatcherTimer();
    myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1); // 1 Milliseconds 
    myDispatcherTimer.Tick += new EventHandler(Each_Tick);
    myDispatcherTimer.Start();
}

// A variable to count with.
int i = 0;

public void Each_Tick(object o, EventArgs sender)
{
    i++;
}

public void keypress(object s, EventArgs args)
{
    label1.contents = i.ToString();
    i = 0;
}

Any ideas?

Answer

Tim Lloyd picture Tim Lloyd · Nov 23, 2010

Start a Stopwatch instead and simply subtract the stopwatch's current elapsed milliseconds from the last elapsed milliseconds (which you need to store in a variable) each time a key is pressed.

    private Stopwatch _stopwatch;
    private int _lastElapsedMs;

    public void StartTimer(object o, RoutedEventArgs sender)
    {
        _lastElapsedMs = 0;
        _stopwatch = Stopwatch.StartNew();
    }

    public void keypress(object s, EventArgs args)
    {
        int elapsedMs = (int)_stopwatch.ElapsedMilliseconds;
        int currentElapsed = (elapsedMs - _lastElapsedMs);

        _lastElapsedMs = elapsedMs;

        label1.contents = currentElapsed.ToString();
    }