11

Possible Duplicate:
Synchronizing a timer to prevent overlap

I have a Threading.Timer in my class.

 System.Threading.Timer timer;
 TimerCallback cb = new TimerCallback(ProcessTimerEvent);
 timer = new Timer(cb, reset, 1000, Convert.ToInt64(this.Interval.TotalSeconds));

and defined a callback for it.

private void ProcessTimerEvent(object obj)
{
  if(value)
    MyFunction();
}

When run it, re-running callback before myfunction to complete.

How to pause Threading.Timer to complete myfunction?

Community
  • 1
  • 1
ar.gorgin
  • 4,765
  • 12
  • 61
  • 100
  • I think you want to prevent [timer overlap](http://stackoverflow.com/questions/684200/synchronizing-a-timer-to-prevent-overlap). – Christian.K Nov 07 '12 at 09:48

2 Answers2

22

It is not necessary to stop timer, you could let the timer continue firing the callback method but wrap your non-reentrant code in a Monitor.TryEnter/Exit. No need to stop/restart the timer in that case; overlapping calls will not acquire the lock and return immediately.

object lockObject = new object();

private void ProcessTimerEvent(object state) 
 {
   if (Monitor.TryEnter(lockObject))
   {
     try
     {
       // Work here
     }
     finally
     {
       Monitor.Exit(lockObject);
     }
   }
 }
Ivan Leonenko
  • 2,363
  • 2
  • 27
  • 37
  • Thanks for the solution. I created a `NonOverlappingTimer` class using this pattern that wraps System.Threading.Timer to guarantee non-overlapping executions: https://gist.github.com/randyburden/fe0febe315d7887b2471c7328a95fe5e#file-nonoverlappingtimer-cs – Randy Burden May 13 '21 at 18:48
16

You can disable a System.Threading.Timer by changing the interval. You can do this by calling:

timer.Change(Timeout.Infinite, Timeout.Infinite);

You'll have to change the interval back once you have finished calling myfunction if you want the timer to continue firing again.

Adrian Thompson Phillips
  • 6,893
  • 6
  • 38
  • 69