I have a timer thread function
SampleTimer = new Timer(SomeTask,0,70000)
call back function is as below
void SomeTask(object o)
{
//block using autoresetevent
}
The issue is the SomeTask() callback method gets called every 70 secs even though all the operations in the callback method is still not done. How can I prevent the timer from calling the SomeTask() function before all the steps within it are completed
I believe the
object o
is the timer being fired. So you may be able to do:(but I would check on that...)
It will fire on your interval no matter how long your
SomeTask
takes.I always do something like this
UPDATE: a bit safer with a lock.
To be super duper safe. And if you only ever want one instance of "SomeTask" running. AND, you don't want them to queue up. You should put a lock() in SomeTask. And you can skip disabling the timer.
I assume you're using a
System.Threading.Timer
.One way to do it is to create the timer as a one-shot, and then restart it after the thread has completed its task. That way you're certain that you won't have any overlap:
And in your callback:
Specifying
Timeout.Infinite
for the period disables periodic signaling, turning the timer into a one-shot.Another way is to use a monitor:
If you're wondering why I don't use a
try/finally
for the lock, see Eric Lippert's blog, Locks and exceptions do not mix.The primary difference in these two approaches is that in the first the timer will fire 70 seconds after the previous callback execution finishes. In the second the timer will fire on a 70 second period, so the next callback might execute any time after the previous one finishes, from one second later to 70 seconds later.
For most things I've done, the first technique I showed seems to work better.
Concurrent invocations are possible which is a very annoying property of .NET and Windows timers. You have to ensure mutual exclusion yourself, maybe just using a lock (no events necessary). That gives you another problem though because if the timer ticks too fast an arbitrary number of threads might queue up in front of the lock. So it is better to
TryEnter
the lock and do nothing if it cannot be entered. You loose one tick that way but as ticks are not guaranteed anyway your application must be able to cope with that.When working with timers very little is ever guaranteed about the time, count and concurrency of ticks.