← All articles

Connecting a Quartz job to a trigger

Quartz separates the work from its schedule: IJob describes execution and a trigger describes timing.

t.Turgay
Connecting a Quartz job to a trigger

A scheduled task has two separate questions: what should run, and when should it run? Quartz expresses them through IJob and Trigger. The small scheduler example in my archive is useful for showing why setting an alarm and completing the business operation are different events.

Keep behavior separate from its schedule

HelloJob only writes job to the console. JobBuilder creates a definition for that behavior, while TriggerBuilder defines its schedule. This is a Quartz 3.x console integration example, not a complete durable production scheduler.

using Quartz;
using Quartz.Impl;
var scheduler=await new StdSchedulerFactory().GetScheduler();
await scheduler.Start();
var job=JobBuilder.Create<HelloJob>().WithIdentity("demo").Build();
var trigger=TriggerBuilder.Create().StartNow()
    .WithSimpleSchedule(s=>s.WithIntervalInSeconds(1).WithRepeatCount(1)).Build();
try { await scheduler.ScheduleJob(job,trigger); await Task.Delay(2500); }
finally { await scheduler.Shutdown(waitForJobsToComplete:true); }
public class HelloJob:IJob
{
    public Task Execute(IJobExecutionContext context)
    { Console.WriteLine("job"); return Task.CompletedTask; }
}

WithRepeatCount(1) means one repetition after the initial execution, normally giving two executions in total. StartNow makes the first firing immediately eligible. Task.Delay provides a short observation window; it is not proof that a loaded machine must complete both executions within exactly that interval.

A job definition has its own identity

A JobKey identifies a particular job definition. Several definitions can use the same IJob class, and multiple triggers can target one definition. That avoids duplicating behavior just to assign a different schedule. It also means restart behavior needs a deliberate policy for existing identities rather than adding arbitrary new names on every startup.

For schedules generated from database records, stable identity and explicit update/removal behavior prevent obsolete definitions from accumulating. The relationship between job and trigger is part of the lifecycle, not just registration syntax.

Decide what happens when executions overlap

An execution can outlast its trigger interval. DisallowConcurrentExecution applies to the same job definition; it should not be interpreted as globally serializing every instance of the same class under different JobKeys. A multi-process deployment also needs appropriate job-store and clustering choices.

Preventing overlap does not make side effects idempotent. If the process finishes a write but crashes before recording completion, a later execution can repeat it. A unique business operation key, persisted outcome or version check may still be needed outside the scheduling layer.

Missed schedules need a business policy

A durable store and misfire policy govern how missed firing times are handled. Replaying every missed report and refreshing only the latest state are different requirements. A daily report and a current-state refresh may legitimately need different recovery behavior. A scheduler default should not accidentally become the product's definition of catch-up work.

The finally block requests shutdown, and waitForJobsToComplete selects waiting for in-progress work. It does not make unbounded execution acceptable. Real I/O calls need cancellation and timeouts compatible with the host's shutdown budget.

Observe completion rather than just firing

Console output is a reasonable demonstration, but an automated test should observe completed executions by identity through a controlled counter or test store. Failures and cancellations should not count as successful work. A fired trigger does not establish that a notification was delivered or a database write committed.

Quartz 3.x jobs and triggers; SimpleTrigger repetition and misfires.

✳ You have reached the end of this orbit.
Explore more articles →
turgay.A little code, a few pixels, a lot of curiosity.© 2026 · Made on Earth ✳