Question

This is my requirement.

Main Job: Job1 (Scheduled to run every 5 mins) Subsidiary Jobs: Job2, Job3, Job4, Job5, etc., (All subsidiary jobs will have same definitions but only JobData will differ)

During every execution of "Job1" one subsidiary job will be scheduled to be executed only once. Example: 1st Execution of Job1: Job "Job2" will be scheduled 2 mins from DateTime.Now 2nd Execution of Job2: Job "Job3" will be scheduled 2 mins from DateTime.Now ...

Now, I want the same Scheduled to be used by all the jobs. My Question is whether Quartz utilizes the same scheduler for all the jobs or should we programmatically set that??

I'm using a Windows Service to Start and Stop the whole process. Here is the code of the Windows Service.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;

namespace TestScheduling
{
    class TestMainClass : ServiceBase
    {
        TestJobScheduler scheduler = new TestJobScheduler();

        public TestMainClass()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            try
            {
            scheduler.StartScheduler();
                scheduler.ScheduleMainJob();
            }
            catch (Exception e)
            {
                //Capture Exception
            }
        }

        protected override void OnStop()
    {
        scheduler.StopScheduler();
    }
    }
}

Here is the Code for the Class TestJobScheduler.

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Data.Odbc;
using Quartz;
using Quartz.Impl;

namespace TestScheduling
{
    class TestJobScheduler : ITaskScheduler
    {
        IScheduler sched;

        public void ScheduleMainJob()
        {
            ....
            sched = getScheduler();
            sched.ScheduleJob(job1,trig);
            ....
            ScheduleSubsidiaryJob("job2")
        }

        public void ScheduleSubsidiaryJob(String jobname)
        {
            ...
            /*Create New Trigger and Associate Subsidiary Job with new JobData*/
            sched = getScheduler();
            sched.ScheduleJob(trig);
        }

        public IScheduler getScheduler()
        {
            ISchedulerFactory sf = new StdSchedulerFactory();
            return sf.GetScheduler();
        }

        public void StartScheduler(IJobDetail job, ISimpleTrigger trigger)
        {
            sched = getScheduler();
            sched.Start();
        }

        public void StopScheduler()
        {
            if (sched != null)
            {
                sched.Shutdown();
            }
        }
    }
}

One More point is that I'm using AdoJobStore with OracleDelegate.

Can someone tell me whether I'm doing things in a right way??

Was it helpful?

Solution

You could have a look at the Quartz.Server sample that comes with the Quartz.NET zip distribution. Also available straight on GitHub:

https://github.com/quartznet/quartznet/tree/master/server/Quartz.Server

You should share the same scheduler. Only create scheduler factory once and get the singleton scheduler from there.

You could have your job added just once to scheduler as durable and parameterize it with trigger job data map. You can then access the combined job and trigger data from MergedJobDataMap that comes with job execution context.

Every triggering instantiates a new instance of the job so job detail acts as an template here.

Please note that DateTime.Now might not be what you want. For Quartz.NET 'now' is DateTime.UtcNow (or even better DateTimeOffset.UtcNow).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top