AFetter
AFetter

Reputation: 3584

TimerCallback in MVC3

I crested this simples code to execute a method every midnight, I have a shared host (impossible create a windows schedule), but this doesn't work. Any idea?

 protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        ControllerBuilder.Current.DefaultNamespaces.Add("PhotoPremier.Controllers");

        var dt = NextAt(new TimeSpan(0, 0, 0)); //
        var timer = new Timer(new TimerCallback(callback), HttpContext.Current, dt - DateTime.Now, TimeSpan.FromHours(24));

    }

    static void callback(Object stateObject) 
    {
        DbLayer.ContestManager cm = new DbLayer.ContestManager();
        cm.UpdateAllPhotosInContest();
    } 

    DateTime NextAt(TimeSpan time)
    {
        DateTime now = DateTime.Now;
        DateTime result = now.Date + time;

        return (now <= result) ? result : result.AddDays(1);
    }

Upvotes: 1

Views: 840

Answers (3)

spickesj
spickesj

Reputation: 21

When I was recently trying to do the same thing, I discovered that my problem was declaring my Timer object somewhere that it get's garbage collected. If you make timer a member of your class instead of declaring it locally in Application_Start, I think the Original Poster's code will work.

Hope this helps someone.

Upvotes: 0

AFetter
AFetter

Reputation: 3584

I think the Unique solution is use the Quarts.Net Framework.

Is very simples and in this here with a simples code.

public class DailyJob : IJob
{
    public DailyJob() { }

    public void Execute( JobExecutionContext context )
    {
        try {
            DbLayer.ContestManager cm = new DbLayer.ContestManager();
            cm.UpdateAllPhotosInContest();
        } catch( Exception e ) {
            //Handle this please
        }
    }

    public static void ScheduleJob( IScheduler sc )
    {
        JobDetail job = new JobDetail("FinishContest", "Daily", typeof(DailyJob));
        sc.ScheduleJob(job, TriggerUtils.MakeDailyTrigger("trigger1", 0, 0));
        sc.Start();
    }
}

//Global.asax
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            /* HERE */ DailyJob.ScheduleJob(new StdSchedulerFactory().GetScheduler());
        }

Upvotes: 0

Leonardo Garcia Crespo
Leonardo Garcia Crespo

Reputation: 601

This may be due to IIS settings in the shared hosting.

By default, IIS configuration shuts down the application after a certain amount of time without anyone accessing it. Also IIS recycles the application pools every some minutes.

Unless you are able to control this settings, you will find a hard time to keep the app alive and fire the trigger for the timer.

To clarify this situation and also suggest other alternatives, I give you the following link:

http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

Upvotes: 1

Related Questions