In certain specific cases within our web-based solutions, we would like to have one or several processes running at specific times or specific intervals in order to perform a specific set of tasks. Commonly, this would be used for tasks such as:
- Sending e-mails on a daily basis at a specific time
- Sending notifications on an hourly basis
My original solution for this was to have a few threads running, initiated on Application_Start which would execute code. I assume many people have tried this sort of thing and many people have found that this does not work. The reason this does not work is simple.
Web applications are essentially stateless. Working with static variables on the Application level does not mean that the web application will have a state. IIS will unload inactive web applications. Occasionally, especially on shared hosting environments, IIS will intermittently shut down a web application, frequently to clear up memory.
Some online posts on various websites, describe setting up a thread which pings the website every 5 minutes or so, thus keeping the web application alive. I have tested this on a shared hosting environment on GoDaddy, which though admittedly is not the best web hosting environment available, is no different for the purposes of this test case. The result of the automated website pinger is that the website itself stays active for a few hours and then gets randomly unloaded by IIS, hence terminating my threads. In short, this solution appears to work, but it does not work.
Hence, we can move on to an improved solution. This solution would ideally be developed for a dedicated hosting environment where you would have access to the windows machine through Remote Desktop and would be able to deploy a windows service. Alternatively you could setup the windows service to execute on your machine and interact with your website. In either case, the solution is the same.
A Windows Service will call a Web Service every 5 minutes. This web service then invokes the Process Code. Within the process code, we can do whatever we like.
Ideally what we would do is keep information within a database, specifying the Next Execution Time. What we would do then, is check on invocation if the date and time are greater or equal to the current date and time. If it is, we execute the process code. On execution, we would then reset the Next Execution Time by our specified delay time.
I will create a prototype eventually, which will be available within the Downloads section.