Home
    Shop
    Advertise
    Write For Us
    Affiliate
    Newsletter
    Contact

Scheduled Tasks in ASP.NET

Very often, there is a need to execute some code on certain date and time, or to repeat execution in regular time intervals. In case of ASP.NET web application, that could be sending of reminder e-mails, analyze traffic data, creating reports, maintenance tasks etc. ASP.NET doesn't provide some straightforward way to schedule tasks. Also, only what HTTP protocol can do is to return some output as a response after receives web request.

 

Fortunately, there are numerous solutions to solve this problem. Scheduled tasks methods could be divided in two groups:

- Pure ASP.NET methods, like using of timer, cache expiration or threads,
- Using of external application, like Windows Task Scheduler, Windows service, web hosting automation program etc.

In this tutorial, I will show three ways to simulate scheduled tasks using ASP.NET only. To learn more about options for scheduled tasks in ASP.NET using external application see Task Scheduler or Windows service in ASP.NET tutorial.

ASP.NET only methods are often an option if you have shared hosting, but they have some drawbacks.

Scheduled tasks using threading

Solution that uses threads is very simple. We'll use Application_Start procedure in Global.asax to initially start task. Then, in separate thread we'll call task again in regular time intervals. Code in Global.asax could look like this:

[ C# ]

<%@ Application Language="C#" %>
<%-- We need this namespace to work with threads --%>
<%@ Import Namespace="System.Threading" %>
   
   <script runat="server">
   
   
   void Application_Start(object sender, EventArgs e)
   {
   // On application start, create an start separate thread
   ThreadStart tsTask = new ThreadStart(TaskLoop);
   Thread MyTask = new Thread(tsTask);
   MyTask.Start();
   
   }
   
   static void TaskLoop()
   {
   // In this example, task will repeat in infinite loop
   // You can additional parameter if you want to have an option
   // to stop the task from some page
   while (true)
   {
   // Execute scheduled task
   ScheduledTask();
   
   // Wait for certain time interval
   System.Threading.Thread.Sleep(TimeSpan.FromHours(12));
   }
   }
   
   static void ScheduledTask()
   {
   // Task code which is executed periodically
   
   }
   </script>

[ VB.NET ]

<%@ Application Language="VB" %>
<%-- We need this namespace to work with threads --%>
<%@ Import Namespace="System.Threading" %>
<script runat="server"> 
   
   Protected Sub Application_Start(ByVal sender As Object, ByVal e As System.EventArgs)
   ' On application start, create an start separate thread
   Dim tsTask As ThreadStart = New ThreadStart(AddressOf TaskLoop)
   Dim MyTask As Thread = New Thread(tsTask)
   MyTask.Start()
   End Sub
   
   Shared Sub TaskLoop()
   ' In this example, task will repeat in infinite loop
   ' You can additional parameter if you want to have an option
   ' to stop the task from some page
   While (True)
   
   ' Execute scheduled task
   ScheduledTask()
   
   ' Wait for certain time interval
   System.Threading.Thread.Sleep(TimeSpan.FromHours(12))
   End While
   End Sub
   
   Shared Sub ScheduledTask()
   ' Task code which is executed periodically
   
   End Sub
 </script>

Scheduled tasks using timers

Very simple solution to perform scheduled tasks is by using timer. Again, we'll use Global.asax and Application_Start procedure. In Application_Start we'll create a Timer and use Elapsed event to execute task in regular time intervals. To make it so, write this code in Global.asax file:

[ C# ]

<%@ Application Language="C#" %>
   
   <script runat="server">
   
   // Code that runs on application startup
   void Application_Start(object sender, EventArgs e)
   {
   // Dynamically create new timer
   System.Timers.Timer timScheduledTask = new System.Timers.Timer();
   
   // Timer interval is set in miliseconds,
   // In this case, we'll run a task every minute
   timScheduledTask.Interval = 60 * 1000;
   
   timScheduledTask.Enabled = true;
   
   // Add handler for Elapsed event
   timScheduledTask.Elapsed +=
   new System.Timers.ElapsedEventHandler(timScheduledTask_Elapsed);
   }
   
   void timScheduledTask_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
   {
   // Execute some task
   FirstTask();
   }
   
   void FirstTask()
   {
   // Here is the code we need to execute periodically
   
   }
   </script>

[ VB.NET ]

<%@ Application Language="VB" %>
   
   <script runat="server">
   Protected Sub Application_Start(ByVal sender As Object, ByVal e As System.EventArgs)
   ' Dynamically create new timer
   Dim timScheduledTask As System.Timers.Timer = New System.Timers.Timer()
   
   ' Timer interval is set in miliseconds,
   ' In this case, we'll run a task every minute
   timScheduledTask.Interval = 60 * 1000
   
   timScheduledTask.Enabled = True
   
   ' Add handler for Elapsed event
   AddHandler timScheduledTask.Elapsed, AddressOf timScheduledTask_Elapsed  
   End Sub
   
   Sub timScheduledTask_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
   ' Execute some task
   FirstTask()
   End Sub
   
   Sub FirstTask()
   ' Here is the code we need to execute periodically
   
   End Sub
   </script>

This solution looks very simple and neat, at least theoretically. In practice, timer is often unstable when used in web application. It is common that timer stops after 20-30 minutes, especially on shared hosting where hosting provider tries to save resources and recycle web application.

Scheduled tasks using cache expiration as a trigger

ASP.NET Cache expiration is one more method you can use to create scheduled tasks. In this method, it is not important what you put in the cache. In this example I added short string "1", but could be anything. Useful for scheduled tasks is the fact that cache expires after specified time interval and then executes selected function (scheduled task).

Here is example of Global.asax file that uses cache expiration to schedule tasks in ASP.NET application. First, Application_Start method calls ScheduleTask procedure that uses cache expiration to schedule when task will be executed. In this example, cache willl expire after one hour. Then, after cache expired, SetTimer() is called. SetTimer function calls DoTask() method which represents code of scheduled task, and also calls again ScheduleTask() function to plan next task execution.

[ C# ]

<%@ Application Language="C#" %>
   
   <script runat="server">
   void Application_Start(object sender, EventArgs e)
   {
   // Schedule task for the first time
   ScheduleTask();
   }
   
   static void ScheduleTask()
   {
   HttpRuntime.Cache.Add(
   // String that represents the name of the cache item,
   // could be any string
   "ScheduledTask",
   // Something to store in the cache
   "1",
   // No cache dependencies
   null,
   // Will not use absolute cache expiration
   Cache.NoAbsoluteExpiration,
   // Cache will expire after one hour
   // You can change this time interval according
   // to your requriements
   TimeSpan.FromHours(1),
   // Cache will not be removed before expired
   CacheItemPriority.NotRemovable,
   // SetTimer function will be called when cache expire
   new CacheItemRemovedCallback(SetTimer));
   }
   
   // This function si called when cache is expired
   static void SetTimer(string key, Object value, CacheItemRemovedReason reason)
   {
   // Call the task function
   DoTask();
   // Schedule new execution time
   ScheduleTask();
   }
   
   static void DoTask()
   {
   // Task code which is executed periodically
   // In this example, code will be executed every hour
   }
   </script>

[ VB.NET ]

<%@ Application Language="VB" %>
   <script runat="server">
   Protected Sub Application_Start(ByVal sender As Object, ByVal e As System.EventArgs)
   ' Schedule task for the first time
   ScheduleTask()
   End Sub
   
   Shared Sub ScheduleTask()
   ' Cache will expire after one hour
   ' You can change this time interval according
   ' to your requriements
   ' SetTimer function will be called when cache expire
   HttpRuntime.Cache.Add( _
   "ScheduledTask", _
   "1", _
   Nothing, _
   Cache.NoAbsoluteExpiration, _
   TimeSpan.FromHours(1), _
   CacheItemPriority.NotRemovable, _
   New CacheItemRemovedCallback(AddressOf SetTimer))
   End Sub
   
   ' This function si called when cache is expired
   Shared Sub SetTimer(ByVal key As String, ByVal value As Object, ByVal reason As CacheItemRemovedReason)
   ' Call the task function
   DoTask()
   ' Schedule new execution time
   ScheduleTask()
   End Sub
   
   Shared Sub DoTask()
   ' Task code which is executed periodically
   ' In this example, code will be executed every hour
   End Sub
   </script>

Conclusion

Scheduled task could be running of Windows application, script, web page, sending email etc. The problem with pure ASP.NET methods could be insufficient rights, since ASP.NET by default runs as NETWORK SERVICE or ASPNET account which are very limited.

Also, ASP.NET application could restart or even stop work because of numerous reasons. If ASP.NET application stops, scheduled tasks are not executed. If there is nobody on website (no web requests), server could stop application after short time. The possible workaround could be to keep web application alive using scheduled task that will use WebClient class to periodically (e.g. every ten minutes) make web requests to some page.

This doesn't help if ASP.NET application restarts. If task is time critical, consider more reliable options that use external application in Task Scheduler or Windows service in ASP.NET tutorial.

Using of external application is also recommended if you have long and heavy tasks that could hurt web application's performances. If visitors' experience will be bad because of some scheduled task, remove it from web application. In case that you are not able to use Windows service or Task Scheduler because your website is hosted on shared hosting, try to split long and heavy task into multiple short steps.


Tutorial toolbar:  Tell A Friend  |  Add to favorites  |  Feedback  |   Google