2

I am experiencing a strange thing in my WPF app. I have experimented with DispatcherTimer and System.Timers.Timer class and comparing the time spent with a stopwatch. When I use DispatcherTimer, there seems to almost no difference in the interval displayed by my app as well as by the stopwatch(tested for 30 mins). But when I use the other Timer, I significantly lose time in my application. I could have use the DispatcherTimer, but here's the problem: when I update my UI from someplace else, the dispatcher timer seems to freeze for that particular interval and hence , it also looses time. Why is this happening and how to rectify it?

Joey
  • 344,408
  • 85
  • 689
  • 683
androider
  • 982
  • 6
  • 16
  • 32
  • 1
    [This question](http://stackoverflow.com/questions/1111645/comparing-timer-with-dispatchertimer) helps maybe. – Joey Jun 19 '14 at 07:30
  • Nah, I actually posted after reading that link. I am not getting why the System.Threading.Timer is loosing so much time approx. 3sec. in 5 min. while dispatcher looses nothing.if my some other process was causing this delay, then it should also reflect in the dispatcher, I guess – androider Jun 19 '14 at 07:41
  • 1
    Generally with timers they all have different uses. That's why I linked that question. And furthermore, I would never expect timers to be accurate, either. Whether they are depends on a lot of things, e.g. system load. – Joey Jun 19 '14 at 07:51
  • but still 2 sec.(or more) in 5 min. is a lot to loose. Any suggestions still? – androider Jun 19 '14 at 07:57

2 Answers2

1

In the comments, @Joey suggested that the answer to the Comparing Timer with DispatcherTimer question might help. Your response was

Nah, I actually posted after reading that link. I am not getting why the System.Threading.Timer is loosing so much time approx. 3sec. in 5 min. while dispatcher looses nothing.if my some other process was causing this delay, then it should also reflect in the dispatcher, I guess

However, if you had read the answer to the linked question, then you've already had your answer. As stated there, it's because the Timer class is optimised to work on Windows Forms Applications and you're using it on a WPF Application. It's a bit like driving a car on the sand... we're not supposed to do it and we might get unexpected results.

My suggestion is for you to simply use the correct tool for the job. It's also worth noting that no computer timers, or even the Stopwatch class that you're using to get your test results with, will be 100% accurate, due to the fact that the processor that it is running on will also be used to run many other threads concurrently.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183
0

The DispatcherTimer is used by the same thread that does all the WPF GUI processing, for example rendering, which has a higher priority than the default settings of the DispatcherTimer. This mean if the WPG GUI thread needs to update something in the display or the user has moved the mouse over a new control or for any other reason, the WPF GUI thread might be busy with higher priority work.

There are 2 ways how you can improve the precision of the DispatcherTimer

  1. give DispatcherTimer a higher priority
DispatcherTimer timer = new(DispatcherPriority.Input);

This is a bit faster than the default DispatcherTimer priority of DispatcherPriority.Background, but rendering has still a higher priority. If the DispatcherTimer has a higher priority than rendering, like DispatcherPriority.Send, the highest priority, then the user might see a sluggish GUI when the DispatcherTimer needs some time for processing.

  1. Call the next DispatcherTimer.Tick earlier, when the GUI thread caused a delay.

Your DispatcherTimer.Tick method can compare the time when it was supposed to run and when it was actually running. If there is a delay of x milliseconds, then shorten `DispatcherTimer.Interval' by x milliseconds.

I wrote a detailed article about this on CodeProject: Improving the WPF DispatcherTimer Precision

Peter Huber
  • 3,052
  • 2
  • 30
  • 42