3

I've long toyed with the idea of some kind of auto-cleanup page that performs routine maintenence tasks and is called out of scope of the current page execution by means of calling a 1x1 pixel gif with the asp.net page as the src parameter. One thing I've never really decided on, however, is how to handle the timing of such a page's execution so that it doesn't execute with every request, maybe like.. every 5th request. or every 30 minutes or some other interval.

How would you consider building such a mechanism?

Chris
  • 27,596
  • 25
  • 124
  • 225
  • Are the kind of clean-up and maintenance tasks you have in mind ASP.NET specific? Are you limited by how you can schedule these tasks, which has led you to consider using the technique of being triggered by requests from browsers? Can the applicable code clean-up after itself instead? – J c Nov 15 '08 at 01:11
  • The kind of code cleanup I'm talking about is when files or data is stored during a session and the session is abandoned. I run a web farm that services multiple applications and the session_end event is unreliable in this environment. – Chris Nov 16 '08 at 03:27

5 Answers5

4

I have come across this situation many times and I generally just end up using task scheduler to just call the page, that way it is consistent and reliable. The problem with relying on a page to be called is that you have to be sure that there will always be requests to your page. If you can guarantee that, then just store a variable at the application level with the timestamp of the last time the task was run and have every page check that timestamp and update it once a request comes in that has passed a certain threshold.

John Lemp
  • 5,029
  • 3
  • 28
  • 36
  • This is definitely the most reliable and simplest option. – Robert Wagner Nov 15 '08 at 03:04
  • This was the most recent solution I used - a simple windows scheduled task that ran a wget on the page. Glad to know it makes sense to someone else too. – Chris Nov 16 '08 at 02:59
4

It sounds like you might want to use the global.asax file instead - assuming you want something to happen every Nth time. For example, if you wanted to do something for every 5th visitor to your site, you could do something along the lines of,

void Application_Start(object sender, EventArgs e) 
{
    // Code that runs on application startup
    Application["Sessions"] = 0;
}

void Session_Start(object sender, EventArgs e) 
{
   // Code that runs when a new session is started
   Application.Lock();
   Application["Sessions"] = (int)Application["Sessions"] + 1;

   if ((int)Application["Sessions"] % 5 == 0)
   {
     DoSomething();
     Application["Sessions"] = 0;
    }
    Application.UnLock();
}

I would heavily recommend something along these lines rather than attaching a script to the source of a GIF file. You have much more control and security.

Anjisan
  • 1,789
  • 3
  • 15
  • 26
  • You could also kick off a background thread in Application_Start that sleeps and does the tasks you want. However you if no one visits, it will eventually stop as the application pool gets killed. The only way around that is to have scheduled task. – Robert Wagner Nov 15 '08 at 03:02
  • If the application isn't running, odds are your background process doesn't really need to either. – Joel Coehoorn Nov 15 '08 at 05:56
1

Have you considered using a windows service instead? Running your cleanup tasks would take up a thread from the ASP.NET thread pool. Or if you're cleaning up a SQL Server database, maybe a SQL Server Agent job would be better.

Maxam
  • 4,043
  • 2
  • 24
  • 25
  • If it was just SQL cleanup, a SQL job would be perfect, but often it involves file system related tasks, such as cleaning up abandoned user uploads and such. – Chris Nov 16 '08 at 02:58
1

Related entry from the stackoverflow blog : https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/.

Others:

Note a few solutions don't work if you lack steady, consistent traffic. If IIS unloads your app, Cache, Session, and Request approaches don't work.

If it's possible, install a Windows task service per service. Work out a scheme to add/remove tasks dynamically.

If your app is hosted and you can't install a service, consider hitting it with a site monitor - something like siteuptime. This keep your app in memory, allows you to hit a handler or action page versus a dummy image, and lets you decide exactly when it runs.

Community
  • 1
  • 1
Corbin March
  • 25,526
  • 6
  • 73
  • 100
  • I absolutely hate developing windows services for this purpose. Most of our projects are short term sites build around supporting product launches or events, and I hate the idea of cluttering the server with services to support 10-20 web sites. I agree it's the best approach, but not one I like. – Chris Nov 16 '08 at 03:01
  • I understand the aversion to many services. Consider one service per server with configurable tasks or dynamically loaded task assemblies. – Corbin March Nov 16 '08 at 06:41
0

I would set a timer and run the cleanup task when the timer fires. If you'd like to base the cleanup on the number of requests, you could make a shorter timer interval and then check the request count when the timer fires; if the request count is too low, then skip the cleanup.

jdigital
  • 11,926
  • 4
  • 34
  • 51