System.Threading.Timer in C# it seems to be not working. It runs very fast every 3 second
This is not the correct usage of the System.Threading.Timer. When you instantiate the Timer, you should almost always do the following:
_timer = new Timer( Callback, null, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
This will instruct the timer to tick only once when the interval has elapsed. Then in your Callback function you Change the timer once the work has completed, not before. Example:
private void Callback( Object state )
{
// Long running operation
_timer.Change( TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
}
Thus there is no need for locking mechanisms because there is no concurrency. The timer will fire the next callback after the next interval has elapsed + the time of the long running operation.
If you need to run your timer at exactly N milliseconds, then I suggest you measure the time of the long running operation using Stopwatch and then call the Change method appropriately:
private void Callback( Object state )
{
Stopwatch watch = new Stopwatch();
watch.Start();
// Long running operation
_timer.Change( Math.Max( 0, TIME_INTERVAL_IN_MILLISECONDS - watch.ElapsedMilliseconds ), Timeout.Infinite );
}
I strongly encourage anyone doing .NET and is using the CLR who hasn't read Jeffrey Richter's book - CLR via C#, to read is as soon as possible. Timers and thread pools are explained in great details there.
It is not necessary to stop timer, see nice solution from this post:
"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."
private void CreatorLoop(object state)
{
if (Monitor.TryEnter(lockObject))
{
try
{
// Work here
}
finally
{
Monitor.Exit(lockObject);
}
}
}
Is using System.Threading.Timer
mandatory?
If not, System.Timers.Timer
has handy Start()
and Stop()
methods (and an AutoReset
property you can set to false, so that the Stop()
is not needed and you simply call Start()
after executing).