Dotnet provides a server-based timer ( and is different from System.Windows.Forms.Timer and System.Threading.Timer ), allow us to specify a recurring interval at which an event will be raised in our application(or Easy way of executing a task at specified interval).
Below example (c# console application) shows how to create a Timer ,execute a task at specified interval and how to stop Timer gracefully.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Timers;
namespace BackgroundThread_Terminate
{
class Program
{
static void Main(string[] args)
{
using (TimerClass_example1 timerSample = new TimerClass_example1())
{
Console.ReadLine();
}
Console.ReadLine();
}
}
public class TimerClass_example1:IDisposable
{
System.Timers.Timer timer;
long _stopTimer = 0; // 0 for start , 1 for stop
ManualResetEvent manualReset = new ManualResetEvent(false);
public TimerClass_example1()
{
timer = new System.Timers.Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
//call back function excuted on a threadpool thread.
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
//always use try catch in callback
try
{
//gracefully stop timer
if(Interlocked.Read(ref _stopTimer) == 1 )
{
timer.Stop();
//signal the thread which is waiting.
manualReset.Set();
return;
}
Console.WriteLine(string.Format("Executed callback at {0}. Threadpool Thread ID:- {1}", DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId));
//Note #1:- Uncomment below the and note the ThreadID's printed
//Thread.Sleep(2000); //[ Reason for printing different Thread is :- The Elapsed event is raised on a ThreadPool thread. If processing of the Elapsed event lasts longer than Interval, the event might be raised again on another ThreadPool thread. Thus, the event handler should be reentrant.]
}
catch (Exception ex)
{
//log exception and you can stop excuting Timer.
}
}
public void Dispose()
{
StopAndDisposeTimer();
GC.SuppressFinalize(this);
Console.WriteLine("Timer has been disposed");
}
private void StopAndDisposeTimer()
{
Interlocked.Exchange(ref _stopTimer, 1);
//wait 5 secs for signal
if (!manualReset.WaitOne(5000, false))
{
Console.WriteLine("Timer is not stopped gracefully.");
}
timer.Dispose();
}
~TimerClass_example1()
{
Dispose();
}
}
}
No comments:
Post a Comment