IT:AD:Quartz.NET:HowTo:Create a repeating job
Notes
You need * the Scheduler, which is the heart of things: * A JobDescription which contains the description of a Job.
- One Job is created for each event (ie, each Trigger event) and not reused.
- Hence why one needs a JobDescription to hold the info on what class to instantiate as a Job.
- The Job has to implement
IJob
* A Schedule is loosely coupled to the JobDescription.
- It specifies when to Trigger the Scheduler to use the JobDescription to create a new Job instance.
* Info is passed to the job by using the JobDescription's JobDataMap.
- It's merged info as one can merge general info, shared across all instances of the job, and this current specific job.
Example
using System;
using Quartz;
using Quartz.Impl;
class Program
{
static void Main(string[] args)
{
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
// construct job info
IJobDetail jobDetail = JobBuilder.Create<AbstractJob>()
.WithIdentity("myJob")
.Build();
jobDetail.JobDataMap["SomeVar"] = "Hi!";
jobDetail.JobDataMap["Type"] = typeof(SomeOperation);
jobDetail.JobDataMap["Instance"] = System.Activator.CreateInstance(typeof(SomeOperation));
//Create a Trigger:
ITrigger trigger =
TriggerBuilder.Create()
//.ForJob(jobDetail)
.WithCronSchedule("0/1 * * * * ?").StartNow().Build();
sched.ScheduleJob(jobDetail, trigger);
Console.ReadLine();
}
}
[PersistJobDataAfterExecution]
class AbstractJob : Quartz.IJob
{
//Unfortunately, this is new every time:
private IHasCommand _target;
public AbstractJob()
{
Console.WriteLine("Note that new instance is created every time Trigger goes off.");
}
public void Execute(IJobExecutionContext context)
{
//Pick up variables:
JobDataMap mergedJobDataMap = context.MergedJobDataMap;
int counter = mergedJobDataMap.GetIntValue("SomeCounter");
context.JobDetail.JobDataMap.Put("SomeCounter", counter + 1);
Console.WriteLine(counter);
//As contructor invoked every time, this approach won't work:
//if (_target == null){_target = System.Activator.CreateInstance((Type)mergedJobDataMap["Type"]);}
//Instead:
((IHasCommand)mergedJobDataMap["Instance"]).Execute();
//And good to knwo that it doesn't fall apart if calling non existent var:
object o2 = mergedJobDataMap["SomeNonExistentVar"];
Console.WriteLine(context.JobDetail.Key);
Console.WriteLine(context.JobDetail.Description);
//If you want to use the same object every time:
//Console.WriteLine(context.JobDetail.PersistJobDataAfterExecution);
}
}
class SomeOperation :IHasCommand
{
public void Execute()
{
Console.WriteLine("Booya!");
}
}
public interface IHasCommand
{
void Execute();
}