DispatchTimer - Prevent the tick event to be triggered if the previous tick is still running

后端 未结 4 1930
被撕碎了的回忆
被撕碎了的回忆 2021-01-19 13:56

In a Silverlight app, I have a block of code that has to run every 500ms. I am planning o use a DispatcherTimer to achieve this (see code below).

Dispatcher         


        
相关标签:
4条回答
  • 2021-01-19 14:20

    I don't know if DispatchTimer has any clever way to do this but what I would do in this situation is not to try to get the timer to not fire the event but to get the event to do nothing if it has not finished the previous run.

    You can use locks to do this by getting a lock at the beginning of your event handler. If the lock is not available then exit the function (its already running) if you get the lock do the work and then once you've finished the work release the lock.

    The method you want is Monitor.TryEnter and you'll want to make sure that you do your error trapping correctly as with any use of locks.

    0 讨论(0)
  • 2021-01-19 14:28

    In order make the event run successfull without getting a call from your DispatcherTimer again with in the previous tick completes stop the dispatcher timer after entering in to dt_Tick event and at the end of the tick event call the start again which will initializes the IsEnabled of DispatcherTimer again to true.

    0 讨论(0)
  • I would say you skip a tick if it takes too long, otherwise you will get a huge queue because of the lock.

    So in the eventhandler say:

    if(!busy) {
      busy = true;
    
      // some code which could take longer than 500 ms
    
      busy = false;
    }
    
    0 讨论(0)
  • 2021-01-19 14:34

    The DispatcherTimer only runs on the dispatcher thread - so there's no way you could have two handlers running at the same time. It's possible they'll be queued up and run one directly after another, of course - you should check.

    However, you shouldn't be making a web service call in a DispatcherTimer anyway. Do it in a background thread, otherwise you're blocking the UI for updating all the time that you're waiting for the web service. Basically you shouldn't do any long-running work in the UI thread. Use one of the various other timers (e.g. System.Timers.Timer) to regularly perform work on a thread pool thread and use the dispatcher to call back to the UI thread when you've got some data which needs to be displayed on the UI.

    Of course, now you've got the potential problem of the new kind of timer firing multiple times concurrently, on multiple threads. One option to avoid this is to set the AutoReset property to false, and just schedule the next timer tick at the end of the current one.

    0 讨论(0)
提交回复
热议问题