views:

453

answers:

5

Given an ASP.NET application, I need to run a maintenance process on a regular basis (daily, hourly, etc.).

What's the best way to accomplish this without relying on an external process like a scheduled task on the server (assume I don't have access to the server - shared hosting environment).

+2  A: 

One way to do it, if you do not need to do it on a scheduled time, but just needs to clean up "once in a while", is to create a function in your Global.asax Session_OnEnd() that will create a random number between 1 and 100, and if the number is say, 50, you execute the maintenance task.

Offcourse you can reduce the "100" to have the task happen more frequently.

Also there is and article titled 'Simulate a Windows Service using ASP.NET to run scheduled jobs' at http://www.codeproject.com/aspnet/ASPNETService.asp that uses an expiring cache to simulate a timer. It claims it can be run on any hosted site.

If you are using the last one, please read this comment from a post about this technique:

You need to really be careful on the length of the task running. Every new Task is a new Worker Thread and there’s a limited number of those - as it “borrows” a thread from the managed thread pool.

Starting in v3.5 of the Framework the maximum number of threads was increased 10x from 25 to 250. But there’s now a logarithmic startup to them, so as it doles out more threads it gets stingier with them. If you run out of available threads in the managed thread pool - your response times are going to go through the roof.

What you’re really writing here is a messaging/queuing system.

If you’re doing things like updating the cache, then by all means - kick off a new task. If you’re doing something like downloading a secondary HTTP resource or some kind of intensive database work - write a Windows Service and use a Queue that allows you more control over how much you “bite” off each time.

Espo
+10  A: 

Here's the way that StackOverflow does it:

private static CacheItemRemovedCallback OnCacheRemove = null;

protected void Application_Start(object sender, EventArgs e)
{
    AddTask("DoStuff", 60);
}

private void AddTask(string name, int seconds)
{
    OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
    HttpRuntime.Cache.Insert(name, seconds, null,
        DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration,
        CacheItemPriority.NotRemovable, OnCacheRemove);
}

public void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)
{
    // do stuff here if it matches our taskname, like WebRequest
    // re-add our task so it recurs
    AddTask(k, Convert.ToInt32(v));
}

Details: http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

sectrean
A: 

this is an external process and I do not know how reliable but you could set something similar up on a machine that you know is always on www.webcron.org.

Basically what it does is hits a page you request it to on the schedule you request.

You essentially could have anything hit a page on a regular schedule that would kick off your maintenance task.

Jeff and Joel also discussed doing similar things in a recent podcast via other methods.

YonahW
A: 

While the way StackOverflow does this is definitely unique, you may want to monitor this question also, since it relates.

Dale Ragan
+2  A: 

While the Cache solution works for simple cases, if your scheduling needs ever change you'll be out of luck. Instead, you could use Quartz.NET, a port of the popular java framework Quartz, which is very flexible.

Mauricio Scheffer