A recurring theme in web programming is calling a function periodically and/or at a specific date and time. This has two aspects:
- Calling a function on a scheduled basis
- Making sure time-outs don’t interfere
Calling a function on a scheduled basis
To be able to call a function on your web app, you first need an endpoint (a URL) that you can call to kick the function off. In ASP.NET you can do this in several ways:
- Create a page that calls the function.
- Create a handler (ASHX) that calls the function (more efficient than a page).
- Create a WCF service that allows calls with HTTP GET, as discussed in this blog post by Sasi Suryadevara.
With your endpoint in place, you can use the Windows Task Scheduler to invoke the function at any given time and at intervals as low as one minute. With the Windows Task Scheduler you have several options again:
- Create a VB Script that calls the URL, as discussed in this blog post by Steve Schofield.
- Create a PowerShell script that calls the URL (same as option 1, but more modern).
- Have the Windows Task Scheduler open Internet Explorer and open the specified URL (e.g.
C:\PROGRA~1\INTERN~1\iexplore.exe -extoff http://www.google.com, which starts IE without extensions). If you do this, you also need to specify that the Task Scheduler closes IE after 1 minute, which you can do in the Settings tab of the task (Windows 2003), or in the Trigger configuration (Windows 2008), as shown below. NOTE: I’ve found that IE sometimes doesn’t close, even if you tell Windows to close it. Eventually this will cripple your scheduled task.
Task Settings in Windows 2003
Trigger configuration in Windows 2008
Note: In Windows 2008 the dropdowns governing duration and interval show 30 minutes as lowest value. You can in fact change this to 1 minute by editing the text.
Making sure time-outs don’t interfere
A web based call is bound to time-out after a few minutes. If you task takes longer than that, this may abort the call depending on how you programmed it, and what webserver settings are used with regards to disconnected clients. To ensure a time-out does not interfere, you can spawn a new thread and have it call the function. That way the thread handling the request can return a response to the client, and the function is carried out regardless. One issue that may arise there is that the function itself hangs or takes too long. You may want to add logic to ensure that it’s aborted after a certain time, and add logging to notify you of this, and possibly also ensure that the function can only be run by one caller at a time.