DispatchTimer - prevent the tick event from triggering if the previous tick is still running

In a Silverlight application, I have a block of code that needs to run every 500 ms. I plan o using DispatcherTimer to achieve this (see code below).

DispatcherTimer dt = new DispatcherTimer(); dt.Interval = new TimeSpan(0, 0, 0, 0, 500); // 500 Milliseconds dt.Tick += new EventHandler(dt_Tick); dt.Start(); 

However, it may happen that the code block takes more than 500 ms (the code block makes some webservice calls). How to make sure that if a call is currently being made, DispatcherTimer does not raise another event? What are the options and what is the best way? Using locks?

+4
source share
4 answers

DispatcherTimer only works in the dispatcher thread - so you cannot work with two handlers at the same time. Perhaps they will stand in line and run one after another, of course - you should check.

However, you should not make a web service call to DispatcherTimer in any way. Do this in the background thread, otherwise you will block the user interface for updating all the time that you expect for the web service. Basically, you should not work long in the user interface thread. Use one of various other timers (e.g. System.Timers.Timer ) to regularly work on a thread pool thread and use the dispatcher to call back the UI when you have data that needs to be displayed in the user interface.

Of course, now you have the potential problem of a new type of timer operation several times at the same time, on multiple threads. One way to avoid this is to set the AutoReset property to false and simply schedule the next tick by timer at the end of the current one.

+4
source

I would say that you skip the checkmark if it takes too long, otherwise you will get a huge queue due to blocking.

So in the event handler say:

 if(!busy) { busy = true; // some code which could take longer than 500 ms busy = false; } 
+1
source

I don’t know if DispatchTimer has any smart way to do this, but what I will do in this situation is not to try to force the timer not to fire the event, but to prevent the event from doing anything if it did not complete the previous run.

You can use locks for this by getting a lock at the beginning of the event handler. If the lock is not available, exit the function (it is already running), if you close the lock, and then, as soon as you finish work, start the lock.

You want Monitor.TryEnter , and you want to make sure that you are correctly mistaken, as with any locks.

+1
source

To make the event successful without receiving a call from your DispatcherTimer again, in the previous tick, end the dispatcher's stop timer after entering the dt_Tick event, and at the end of the tick event, start again, which again initializes IsEnabled DispatcherTimer to true.

+1
source

All Articles