.NET Framework provides us with three types of Timers, namely:
Server Timer(), Thread Timer( ) and Windows Timer().
Among them, Windows Timer is like Timer in WinAPI, and is message-based and single-threaded. The other two Timers are different from Windows Timers. They are based on ThreadPool. The biggest advantage is that the time intervals generated are accurate and even. The difference between Server Timer and Thread Timer is that Server Timer is based on events, while Thread Timer is based on Callback.
In comparison, Thread Timer is lighter, so the following mainly uses Thread Timer as an example to explain how to use Thread Timer to implement planned tasks in it.
Here is a class that uses Timer to implement planned tasks:
public class ScheduledTask
{
private static readonly ScheduledTask _ScheduledTask = null;
private Timer UpdateTimer = null;
//The interval time is set to 15 minutes here
private int Interval = 15 * 60000;
private int _IsRunning;
static ScheduledTask()
{
_ScheduledTask = new ScheduledTask();
}
public static ScheduledTask Instance()
{
return _ScheduledTask;
}
public void Start()
{
if(UpdateTimer == null)
{
UpdateTimer = new Timer(new TimerCallback(UpdateTimerCallback), null, Interval, Interval);
}
}
private void UpdateTimerCallback(object sender)
{
if((ref _IsRunning, 1) == 0)
{
try
{
// Write the task you want to perform here
}
catch(Exception ex)
{
}
finally
{
(ref _IsRunning, 0);
}
}
}
public void Stop()
{
if(UpdateTimer != null)
{
();
UpdateTimer = null;
}
}
}
First, pay attention to this paragraph: private int _IsRunning;
_IsRunning is a flag that represents whether the task triggered by the previous time interval has completed running.
Why do we need this_IsRunning flag?
Because, if we execute a task for a long time, it may cause the task triggered in the previous time period to not be completed, and the next task will start again, which will cause the problem of reentry. To solve this problem, we use _IsRunning as a flag to indicate whether the last task was completed. If it is completed, we will execute a new task. If it is not completed, skip this task and continue to execute the last task.
The specific logic is implemented in the following code:
Program code
private void UpdateTimerCallback(object sender)
{
if((ref _IsRunning, 1) == 0)
{
try
{
// Write the task you want to perform here
}
catch(Exception ex)
{
}
finally
{
(ref _IsRunning, 0);
}
}
}
As you can see, this method is used in the above code. The function of this method is to ensure the security of assigning values to objects under multiple threads. Because it is not safe for us to directly assign _IsRunning to be assigned directly, it comes in handy in this case.
After talking about the implementation of the ScheduledTask class, let's take a look at how to call this class in it.
It is recommended to call this class in Application_Start, the code is as follows:
Program code
public class Global :
{
protected void Application_Start(object sender, EventArgs e)
{
().Start();
}
protected void Application_End(object sender, EventArgs e)
{
().Stop();
}
}
OK, the above is the simple application of Timer. If there is anything wrong with it, please give me some advice.
Server Timer(), Thread Timer( ) and Windows Timer().
Among them, Windows Timer is like Timer in WinAPI, and is message-based and single-threaded. The other two Timers are different from Windows Timers. They are based on ThreadPool. The biggest advantage is that the time intervals generated are accurate and even. The difference between Server Timer and Thread Timer is that Server Timer is based on events, while Thread Timer is based on Callback.
In comparison, Thread Timer is lighter, so the following mainly uses Thread Timer as an example to explain how to use Thread Timer to implement planned tasks in it.
Here is a class that uses Timer to implement planned tasks:
public class ScheduledTask
{
private static readonly ScheduledTask _ScheduledTask = null;
private Timer UpdateTimer = null;
//The interval time is set to 15 minutes here
private int Interval = 15 * 60000;
private int _IsRunning;
static ScheduledTask()
{
_ScheduledTask = new ScheduledTask();
}
public static ScheduledTask Instance()
{
return _ScheduledTask;
}
public void Start()
{
if(UpdateTimer == null)
{
UpdateTimer = new Timer(new TimerCallback(UpdateTimerCallback), null, Interval, Interval);
}
}
private void UpdateTimerCallback(object sender)
{
if((ref _IsRunning, 1) == 0)
{
try
{
// Write the task you want to perform here
}
catch(Exception ex)
{
}
finally
{
(ref _IsRunning, 0);
}
}
}
public void Stop()
{
if(UpdateTimer != null)
{
();
UpdateTimer = null;
}
}
}
First, pay attention to this paragraph: private int _IsRunning;
_IsRunning is a flag that represents whether the task triggered by the previous time interval has completed running.
Why do we need this_IsRunning flag?
Because, if we execute a task for a long time, it may cause the task triggered in the previous time period to not be completed, and the next task will start again, which will cause the problem of reentry. To solve this problem, we use _IsRunning as a flag to indicate whether the last task was completed. If it is completed, we will execute a new task. If it is not completed, skip this task and continue to execute the last task.
The specific logic is implemented in the following code:
Program code
private void UpdateTimerCallback(object sender)
{
if((ref _IsRunning, 1) == 0)
{
try
{
// Write the task you want to perform here
}
catch(Exception ex)
{
}
finally
{
(ref _IsRunning, 0);
}
}
}
As you can see, this method is used in the above code. The function of this method is to ensure the security of assigning values to objects under multiple threads. Because it is not safe for us to directly assign _IsRunning to be assigned directly, it comes in handy in this case.
After talking about the implementation of the ScheduledTask class, let's take a look at how to call this class in it.
It is recommended to call this class in Application_Start, the code is as follows:
Program code
public class Global :
{
protected void Application_Start(object sender, EventArgs e)
{
().Start();
}
protected void Application_End(object sender, EventArgs e)
{
().Stop();
}
}
OK, the above is the simple application of Timer. If there is anything wrong with it, please give me some advice.