. NET Framework provides three types of Timer for us:
Server Timer (System. Timers. Timer), Thread Timer (System. Threading. Timer), and Windows Timer (System. Windows. Forms. Timer ).
The Windows Timer is message-based and single-threaded, like the Timer in WinAPI. The other two timers are different from Windows Timer, which are based on ThreadPool. The biggest advantage is that the generated time interval is 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 contrast, Thread Timer is more lightweight, so the following describes how to use Thread Timer to implement scheduled tasks in ASP. NET.
The following is a class that uses Timer to implement scheduled tasks:
Public class ScheduledTask
{
Private static readonly ScheduledTask _ ScheduledTask = null;
Private Timer UpdateTimer = null;
// Interval, which is set to 15 minutes
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 (Interlocked. Exchange (ref _ IsRunning, 1) = 0)
{
Try
{
// Write the task you want to execute here
}
Catch (Exception ex)
{
}
Finally
{
Interlocked. Exchange (ref _ IsRunning, 0 );
}
}
}
Public void Stop ()
{
If (UpdateTimer! = Null)
{
UpdateTimer. Dispose ();
UpdateTimer = null;
}
}
}
First, pay attention to this section: private int _ IsRunning;
_ IsRunning indicates whether the task triggered at the previous interval is completed.
Why do we need the _ IsRunning mark?
Because, if we execute a task for a long time, it may cause that the task triggered in the previous time period has not been completed, and the next task has started again, which will cause re-import problems. To solve this problem, we use _ IsRunning as a flag to indicate whether the previous task has been completed. If so, we will execute the new task, if the task is not completed, skip this task and continue to execute the previous task.
The specific logic is implemented in the following code:
Program code
Private void UpdateTimerCallback (object sender)
{
If (Interlocked. Exchange (ref _ IsRunning, 1) = 0)
{
Try
{
// Write the task you want to execute here
}
Catch (Exception ex)
{
}
Finally
{
Interlocked. Exchange (ref _ IsRunning, 0 );
}
}
}
As you can see, the Interlocked. Exchange method is used in the above Code. This method ensures the security of assigning values to objects under multiple threads. In multi-thread scenarios, it is insecure to assign a value to _ IsRunning directly, so Interlocked. Exchange can be used in this case.
After completing the implementation of the ScheduledTask class, let's take a look at how to call this class in ASP. NET.
We recommend that you call this class in Application_Start. The Code is as follows:
Program code
Public class Global: System. Web. HttpApplication
{
Protected void Application_Start (object sender, EventArgs e)
{
ScheduledTask. Instance (). Start ();
}
Protected void Application_End (object sender, EventArgs e)
{
ScheduledTask. Instance (). Stop ();
}
}
OK. The above is a simple application of Timer in ASP. NET. If there is anything wrong with it, please give me more advice.