7

I would like to have a timer for an ASP.net application that will kick off every Sunday night and perform something (update a table in the database). However, I really don't want to write up a service that has to be deployed on the server in addition to the web application. Is there a way to accomplish this easily? Perhaps using a Global.asax file?

Darwyn
  • 4,696
  • 3
  • 25
  • 26
  • 1
    I don't believe a web-app is the right tool for this, but if you go ahead an important consideration: turn off IIS recycling if you plan your app to be up on such long schedules! – annakata May 28 '09 at 20:58
  • 1
    duplicate: http://stackoverflow.com/questions/542804/asp-netbest-way-to-run-scheduled-tasks – Mauricio Scheffer May 28 '09 at 21:20
  • 2
    @mausch good find... I ended up exploring that question and found http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/ which seems be the best solution for me. – Darwyn May 31 '09 at 05:25

6 Answers6

9

It seems that the best solution was to use this technique. If I had more control over the server I would probably write up a console app to take advantage of scheduled tasks.

Community
  • 1
  • 1
Darwyn
  • 4,696
  • 3
  • 25
  • 26
4

I'm not 100% sure where you would put it, but using a System.Threading.Timer would rock this.

// In some constructor or method that runs when the app starts.
// 1st parameter is the callback to be run every iteration.
// 2nd parameter is optional parameters for the callback.
// 3rd parameter is telling the timer when to start.
// 4th parameter is telling the timer how often to run.
System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(TimerElapsed), null, new Timespan(0), new Timespan(24, 0, 0));

// The callback, no inside the method used above.
// This will run every 24 hours.
private void TimerElapsed(object o)
{
    // Do stuff.
}

Initially, you'll have to determine when to start the timer the first time, or you can turn the site on at the time you want this timer running on Sunday night.

But as others said, use something other than the site to do this. It's way easy to make a Windows service to deal with this.

Gromer
  • 9,861
  • 4
  • 34
  • 55
  • It seems the best place to put a timer like the one in your example would be in the Application_Start handler of the Global.asax file. – Darwyn May 31 '09 at 05:30
  • 1
    You would definitely have to perform a check to ensure this timer is not already running. I can already see someone using this example and spawning thousands of threads because they hooked it into the Application_Start event handler. – Richard Clayton Aug 01 '09 at 05:21
3

I would write a console app and use Scheduled Tasks to schedule it.

jrcs3
  • 2,790
  • 1
  • 19
  • 35
  • Scheduled Tasks would be ideal if I were to have full control over the server...I unfortunately do not. I'm gonna vote up your answer just to raise awareness of this option. – Darwyn May 31 '09 at 05:34
  • Actually, it's a hack, I like the hack, but it's a hack. I added anther answer with another hack you can try. Unfortunately, I don't think ASP.NET directly supports what you want to do. – jrcs3 Jun 01 '09 at 02:47
1

Try the Quartz .NET, a job scheduler for .NET enterprise application such as ASP .NET and this should serve your purpose.

ddt99999
  • 11
  • 1
0

I don't think a .NET application is a good solution to your problem.

IIS Recycling will recycle the process every few hours (depending on the setting) and even if you set that interval to seven days, the application pool can still be recycled for other reasons beyond your control.

I agree with jcrs3: Just write a little console app and use scheduler. You can also write a service, but if you need something quick and easy, go with the console app.

Stefan
  • 1,719
  • 2
  • 15
  • 27
0

In response to your comment about Scheduled Tasks:

Another hack would be to override an event in Global.asax, an even that is called often like Application_EndRequest() and do something similar to:

protected void Application_EndRequest()
{
    if (((DateTime)Application["lastTimeRun"]) < DateTime.Today)
    {
        Application["lastTimeRun"] = DateTime.Today;
        doSomething();
    }
}

This would run after the first request after the date changed, so you wouldn't be guaranteed that this would be run precisely at 3:00 AM every morning.

I've even seed cases where you would hit the site using a Scheduled Task on another computer.

jrcs3
  • 2,790
  • 1
  • 19
  • 35