5,316,172 members and growing! (19,351 online)
Email Password   helpLost your password?
Web Development » ASP.NET » Utilities     Intermediate License: The Code Project Open License (CPOL)

Task scheduler for websites

By maxxnostra

Create scheduled tasks for your website (no 3rd party or heavy coding involved)
VB (VB 7.x, VB 8.0, VB 9.0, VB 6, VB), .NET (.NET, .NET 2.0, .NET 3.0, .NET 3.5), ASP.NET, Architect, Dev, QA, Design

Posted: 21 Mar 2008
Updated: 21 Mar 2008
Views: 4,336
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
3 votes for this Article.
Popularity: 1.70 Rating: 3.57 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
2 votes, 66.7%
3
1 vote, 33.3%
4
0 votes, 0.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

This article will help you build a recurring task scheduler that will execute at specified interval of time. This article overcomes the complexity of scheduling applications that you may find on this site or on internet. This small and easy to understand code overcomes the limitation of installing a web service (with special permission) or windows service or instantiate any other process to run scheduler. It is safe to run on shared hosting provider if coded carefully and with the ability to shut down the task if needed.

Background

First of all let me give a full credit to Michael Taper at angrycoder.com who first wrote the code (idea behind how this works) in C# back in April 2003. I'm giving credit to this guy since it appears that he wrote that article. Since I’ve run into his code in 2008 with ASP.NET 3.5 around and I need to work on the VB.NET version I could not make this code run for me in VB.NET. Also the originals coder description on that site was poor in explaining what his code actually does (it is very high overview)– so I decided to convert his C# code to VB.NET version that will run on today’s .NET version (2.0 or greater as of March 2008) and to bring down to the level for not so advanced coders.

Using the code

I've placed the whole code in single file that is constructed like this:

  1. ISchedulerJob Inteface
  2. Classes that Implemetn the interace above
  3. Scheduler Configuration class
  4. Scheduler Enging class

The ISchedulerJob Interface is only one line of code that will execute each class that it implements it.

Public Interface ISchedulerJob


 Sub Execute()

End Interface


That is plan simple. The sub Execute line tells each class that implements it, that this call must be defined and implement for this interface. This ensured the Execute event will fire on each scheduled job. Now lets get to second step implementing this intefaces in our classes. My need for this scheduler was to check the website database and send e-mail to users that satisfy certain criteria. The logic behind this is not included since it goes beyond the scope of this article.
As any other scheduler application - this code works by having the jobs crated. The job can be anythign you wish (anything you can code to execute) but it has to be wrapped in a class that implements the interface above.

The fist class MailJob is actually reperesents a single job that will be executed on the schedule:

Public Class MailJob 
Implements ISchedulerJob 
 Public Sub Execute() Implements ISchedulerJob.Execute 
   MMCUtil.SendMail("tosomeone@domain.com", _
    "Subject:testing schedule from mail job ",
   "Body:Body of schedule") 
 End Sub 
End Class

You can see that this classs implements Execute sub of our Job Interface and all it does is calling my SendMail function.

The next class is just for demonstration puposes. It represents another job that will be executed at the same time as the MailJob Class.

Public Class OtherJob 
Implements ISchedulerJob 
 Public Sub Execute() Implements ISchedulerJob.Execute 
   MMCUtil.SendMail("tosomeone@domain.com", _
    "Subject:testing schedule from other job ", _
   "Body:Body of other job schedule") 
 End Sub 
End Class

As you can see it does exactly same as previous job but the subject and body are different so it technically is different job to execute.

You can add as many job classes as you like. The job classes does not have to be executed. To include the job in the the execution schedule each job class has to instantiated. I will discuss in more detail later on how to achive this.

The next step is to build configuration class. The configuration has two properties. One Integer that keeps the time (in milliseconds) that you wish to wait before the scheduled jobs execute, and one ArrayList that keeps Jobs to be executed.


Public Class SchedulerConfiguration

       Private m_sleepInterval As Integer
       Private m_jobs As New ArrayList()

        Public ReadOnly Property SleepInterval() As Integer

          Get
               Return m_sleepInterval
           End Get
         End Property
        Public ReadOnly Property Jobs() As ArrayList
            Get
                Return m_jobs
            End Get
        End Property
       Public Sub New(ByVal newSleepInterval As Integer)
           m_sleepInterval = newSleepInterval
        End Sub
End Class

The scheduler engine is the one that makes the jobs run. This is where you will wan to pay some attention (design your code carefully), since the jobs are recurring and the execution is placed in indefinite loop.

Public Class Scheduler 
  Private configuration As SchedulerConfiguration = Nothing 
    Public Sub New(ByVal config As SchedulerConfiguration) 
        configuration = config 
    End Sub 
   Public Sub Start() 
    While True 
         Try 
           For Each job As ISchedulerJob In configuration.Jobs 
             job.Execute() 
           Next 
        Catch
       Finally 
         Thread.Sleep(configuration.SleepInterval) 
       End Try 
     End While
End Sub 
End Class

If you wish to execute the jobs only once at specific time, then simply do not use the while/wend loop and make sure you place a check if the current time (date.Now) is greater then scheduled time. In this case you may also wish to set scedule interval to seconds or minutes. That is all it takes to make the scheduler. To add a Jobs and execute them you need to do the following.

  1. Craeate a new instance of The Scheduler Configuration (in my case 1 hr)
  2. Create the jobs by crating a new instance of each job in the scheduler configuration
  3. Create new instance of the scheduler using the above config
  4. Create a new thread that will start with the sub named Start in the scheduler class
  5. Start the newly created thread
Private schedulerThread As System.Threading.Thread = Nothing 

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
 Dim config As New MailScheduler.SchedulerConfiguration(60 * 60 * 1000)
 config.Jobs.Add(New MailScheduler.MailJob())
 config.Jobs.Add(New MailScheduler.OtherJob())
 Dim scheduler As New MailScheduler.Scheduler(config)
 Dim mailThreadStart As _
   New System.Threading.ThreadStart(AddressOf scheduler.Start)
  schedulerThread = New System.Threading.Thread(mailThreadStart)
  schedulerThread.Start()
End Sub




Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
  If Not IsNothing(schedulerThread) Then
   schedulerThread.Abort()
  End If
End Sub

I've placed the above code in the global.asax on application start with schedulerThread declared as private variable within the scope of global.asax. The reason is because I will need to reference it on application end to kill the same tread . That would be a perfect place or any scheduled task to run and then just continue to the site. Now as the site is working our jobs will execute in a separate thread that sleeps between the jobs executions for a specified period of time.

If you wish the code to run as long as the asp.net worker process is alive leave the scheduler thread (do not abort it). IT IS DANGEROUS to leave any thread open, especially on hosting provider this may cause undesired results. So be WARNED. The safer method is to create public reference to the scheduler thread so you can reference it from within a page and abort it by simply loading the page (on page load event). The approach on how to start and kill the thread is up to you. This article intention was to give a simple code on implementing the scheduler functionality for recurring tasks. You may wish to search this site for more samples on creating safe threading models for your web site.

Happy coding...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

maxxnostra



Location: United States United States

Other popular ASP.NET articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 4 of 4 (Total in Forum: 4) (Refresh)FirstPrevNext
Subject  Author Date 
Generalit works only for a period of time...membergabriele.galeazzi0:32 26 Mar '08  
AnswerRe: it works only for a period of time...membermaxxnostra12:35 26 Mar '08  
QuestionRe: it works only for a period of time...membergabriele.galeazzi23:56 26 Mar '08  
AnswerRe: it works only for a period of time...membermaxxnostra11:22 27 Mar '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 21 Mar 2008
Editor:
Copyright 2008 by maxxnostra
Everything else Copyright © CodeProject, 1999-2008
Web18 | Advertise on the Code Project