tags:

views:

43

answers:

1

I have a System.Timer setup to trigger an event every day at 2AM. If the process the timer starts fails then I want the timer to be reset to run every 15 minutes until the process completes succesfully.

// this is how the timer is set up. 
// this is working correctly.

double startTime = milliseconds_of_hour_to_start.

Timer = new System.Timers.Timer( startTime);

Here is the code to reset the timer on success or failure of the event handler. NOTE the timer is not being stopped, just the Interval property is being reset.

if (ProcessSuccess)
{
  Timer.Interval = TimeSpan.FromHours(24).TotalMilliseconds;
}
else
{
  Timer.Interval = TimeSpan.FromMinutes(15).TotalMilliseconds;
}

My question is this, if the process fails say 4 times, then succeeds will the Timer now be running at around 3AM? i.e. after failing will the original start time of 2AM be advanced by 15 minutes?

+1  A: 

I encourage you to download Reflector, you'll find a quick answer to a question like this. The timer's interval is changed by TimerBase.ChangeTimer(). It takes several measures to ensure the interval update is safe and accurate. The code runs in a finally block so that even a ThreadAbortException cannot mess it up. It acquires a lock (m_lock member) to ensure access is serialized across threads. The ChangeTimerNative() call calls into the CLR to update the native timer. That method is implemented by TimerNative::CorChangeTimer(), it invokes the ChangeTimerQueueTimer() Windows API function. That function is documented to be safe even when called from inside the Elapsed callback function.

Long story short, yes: it has the behavior you are looking for. Beware however the inevitable race condition, the timer might already have elapsed and the threadpool thread that makes the callback may have already been scheduled to run but didn't get a chance to run yet. Getting the callback immediately after changing the timer is not impossible.

Hans Passant