3

Just downloaded Quartz.Net, read the documentation which is out of date and have ended up with the code below which I believe is correct. (Let me know if it isn't)

I put this in my Application_Start of my ASP.Net application and the code gets executed but the job does not run. I think I read somewhere about setting Quartz up as a singleton but not sure if I've done that here?

I want to set this up to run daily at 9.00 but for now have used StartNow to check it works.

Please advise what I have to do?

    private void StartScheduler()
    {
        ISchedulerFactory schedulerFactory = new StdSchedulerFactory();

        IScheduler scheduler = schedulerFactory.GetScheduler();
        scheduler.Start();

        IJobDetail jobDetail = JobBuilder
            .Create()
            .OfType(typeof(DBCleanUpJob))
            .WithIdentity(new JobKey("test", "1"))
            .Build();

        var trigger = Quartz.TriggerBuilder.Create()
                    .ForJob(jobDetail)
                     .WithIdentity(new TriggerKey("test", "1"))
                    .WithSimpleSchedule()
                    .StartNow()
                    .Build();
        //.WithDailyTimeIntervalSchedule(x=>x.StartingDailyAt(new TimeOfDay(09,00)));



        scheduler.ScheduleJob(jobDetail, trigger);
    }

public class DBCleanUpJob : IJob
{
    private IDocumentSession DocumentSession;

    public DBCleanUpJob(IDocumentSession DocSession)
    {
        DocumentSession = DocSession;
    }

    #region IJob Members

    public void Execute(IJobExecutionContext context)
    {
        throw new NotImplementedException();
    }

    #endregion
}
Jon
  • 38,814
  • 81
  • 233
  • 382
  • You should take into care, that this will only work while your application is running in your webserver. As soon as your application gets shut down, the quartz triggers won´t execute anymore. – Jehof Jun 14 '12 at 11:51
  • That's ok. The job is to clear old data from a database that the application uses – Jon Jun 14 '12 at 11:54
  • Then why do you want to execute the trigger at 9:00. If your application (aka. WorkerThread in webserver) isn´t running, no trigger will be executed. – Jehof Jun 14 '12 at 11:56
  • The application will be running, if no users are looking at the site, the application is still running isn't it? – Jon Jun 14 '12 at 12:00

1 Answers1

7

as you said, scheduler should be a singleton. with the code about scheduler is not a singleton and the scheduler only exists in the scope of the application starting, not the application running.

public static IScheduler Scheduler { get; private set; }

private void StartScheduler()
{
    Scheduler = new StdSchedulerFactory().GetScheduler();
    Scheduler.Start();

    var jobDetail = JobBuilder
        .Create()
        .OfType(typeof(DBCleanUpJob))
        .WithIdentity(new JobKey("test", "1"))
        .Build();

    var trigger = Quartz.TriggerBuilder.Create()
                .ForJob(jobDetail)
                .WithIdentity(new TriggerKey("test", "1"))
                .WithSimpleSchedule()
                .StartNow()
                .Build();
    //.WithDailyTimeIntervalSchedule(x=>x.StartingDailyAt(new TimeOfDay(09,00)));

    Scheduler.ScheduleJob(jobDetail, trigger);
}

and as Jehof pointed out. IIS will shutdown a website/application if there is no activity for a certain period of time.

Also note that your jobs will not have access to the asp.net pipeline. the jobs do not execute within the context of a request, therefore session, request, response, cookies are not available to the job.

Finally, if you want the scheduler to always run it will need to be independent of the website. Windows services are a good candidate. create a windows service project and have the scheduler start when the service starts. you could then setup quartz on the website to proxy jobs to the windows service. allowing the site to schedule jobs but the actual storage and execution is performed by the windows service scheduler.

Jehof
  • 34,674
  • 10
  • 123
  • 155
Jason Meckley
  • 7,589
  • 1
  • 24
  • 45
  • Will application_start only happen once for the whole use scenario? If 100 users connect to the website I'm assuming application start only happens once? if IIS shuts down after a while but in the same day I dont want the scheduler to run if a new user comes on board. a service is the best way to go but I dont have that option. – Jon Jun 14 '12 at 12:17
  • Also I have break points in my job class and using your mods, its still not running??? – Jon Jun 14 '12 at 12:18
  • 1
    application_start runs when the website starts. if 5 users access your site this will fire once when the first use accesses the system. it will not fire for the next 4. however if all 5 leave the site will stop. at this point, when the next user visits the site application_start will start again. think of it like opening and closing the browser or MS Word. – Jason Meckley Jun 14 '12 at 12:20
  • can you have static members such as DateTime lastRun or will that be reset when the application stops? I could store it in the db but go with the simplest option first – Jon Jun 14 '12 at 12:21
  • in this reguard think of the web app like a desktop app. it's all in memory, so if you close/stop the app memory is flushed. if you want to store the state of the app then you will need to save that data to disk (db, file, whatever). – Jason Meckley Jun 14 '12 at 12:24
  • also, do you have commonlogging configured? this is required by quartz not to mention provide alot of detail into how the scheduler is configured and whether or not jobs are executing. – Jason Meckley Jun 14 '12 at 12:25
  • I have it referenced but I'm not doing anything with it, will this show me why the job isnt running. See updated question with more code – Jon Jun 14 '12 at 12:26
  • Just thought about it and unless you scheduling something often within an ASP.Net app scheduling a daily thing is diffcult unless you have a constant thread running. I think I may just use Application_Start to read a LastRunDate from the DB, if its greater than 24 hours run the code, no need for Quartz – Jon Jun 14 '12 at 12:49
  • exactly. a web app is good when the user requires an interface. for processes that do not require human interaction a windows service (or console + windows task scheduler is the best choice. – Jason Meckley Jun 14 '12 at 17:45