This is not something new but it might be helpful for someone who needs this solution. I am sharing this as I have a current project to create background services using my Web application. As usual, before I start some solution I check whether I had made something like it before and to my luck after checking my portable drive for past projects, I did have and used it for batch emailing in a website I had made around 2005. With some slight changes, here is how it's done.
Before we start, you might ask why I need to do this on the Web application when I can do it in the Windows service? Well, imagine you have your website hosted on a shared hosting environment which you don’t have access to the operating system. Well, you’re out of luck - your only option at this time is to ask for server permission which in most cases won't be granted or you can run a background method that invokes every page request which is a bad practice, that is why in this solution we will use HttpModule
to act as your background service.
It is basically simple, all you need to do is create a class for your Service and use Timers to invoke the process you want to achieve. Below is the code to do such thing and I will explain to you how it works.
public class Scheduler : IHttpModule
{
protected static Timer timer;
protected static object someAction;
private static readonly ILog Log = LogManager.GetLogger(typeof(Scheduler).Name);
static Scheduler()
{
someAction = new object();
}
void IHttpModule.Init(HttpApplication application)
{
if (timer == null)
{
var timerCallback = new TimerCallback(ProcessSomething);
var startTime = 0;
var timerInterval = 5000;
timer = new Timer(timerCallback, null, startTime, timerInterval);
}
}
protected void ProcessSomething(object state)
{
Log.Info("Invoked Normal Process - " + DateTime.Now);
lock (someAction)
{
Log.Info("Invoked Protected Process - " + DateTime.Now);
System.Threading.Thread.Sleep(20000);
}
}
public void Dispose(){}
}
First, you have your IHttpModule.Init
where everything starts, basically you just need a Timer
and a TimerCallback
to call your process. You can define the wait times or interval on how many seconds you want your process to be called. We also added a line that checks whether the timer is null
as having multiple timers in a Web application is not a good idea.
Next is that you have your method which in this case we call ProcessSomething
, this is then being called by the TimerCallback
every 5 seconds in our example. You notice that we also start at 0 seconds which means it will immediately call one when you website goes online or gets published. Looking further inside ProcessSomething
, there is a lock which protects your process from being executed when the timer ticks again ahead of the running process.
Finally for that to work, you have to place it in your web.config in between system.web
tags inside httpModules
like such:
<system.web>
.
.
.
.
.
<httpModules>
<add type="YourNamespace.Scheduler" name="Scheduler"/>
</httpModules>
</system.web>
Other than that, all should be straightforward, the code is a working sample so here are my results.
If you notice, we log everything in the event logs through that Log.Info
line, and in that log it is visible that ticks happen every 5 seconds but the process only runs when ProcessSomething
finishes (the yellow highlight) in this case after sleeping it for 20 seconds to simulate a long running process.