I am using System.Timers.Timer and every x seconds I need to perform some tasks in an ElapsedEvent method. While I am performing my tasks in the ElapsedEvent method, I want the timer to be stopped. However, I have another method that can start the timer, which can be called while the ElapsedEvent is running. My code looks something like this:
class MyClass {
Timer myTimer;
public MyClass {
myTimer = new System.Timers.Timer();
// init timer code here...
}
public void ElapsedEventTask(object source, ElapsedEventArgs e) {
myTimer.Enabled = false;
try
{
// do my tasks
}
catch
{
...
}
finally
{
myTimer.Enabled = true;
}
}
}
public void AnotherMethod() {
// do some things
myTimer.Enabled = true;
}
How do I prevent AnotherMethod
from starting the timer while I'm completing the task in ElapsedEventTask
?
According to the documentation the
System.Timers.Timer
class is not thread-safe, so it's not safe to touch itsEnabled
property from multiple threads without synchronization (doing so results to undefined behavior). Vernou's answer shows how to synchronize the threads by using locks, but personally I am a bit nervous with trying to enforce a non-overlapping execution policy using a mechanism that apparently was designed to be re-entrant. So my suggestion is to ditch theSystem.Timers.Timer
, and use instead an asynchronous loop, controlled by Stephen Cleary'sPauseTokenSource
mechanism:The
PauseTokenSource
is the controller of aPauseToken
, a similar concept with theCancellationTokenSource
/CancellationToken
combo. The difference is that theCancellationTokenSource
can be canceled only once, while thePauseTokenSource
can be paused/unpaused multiple times. This class is included in the AsyncEx.Coordination package.The
MyClass
exposes aComplete
method that terminates the asynchronous loop, and aCompletion
property that can be awaited. It is a good idea toawait
this property before closing the program, to give to any active operation the chance to complete. Otherwise the process may be killed in the middle of a background execution, with unpredictable consequences.