Quartz allows passing data to jobs through various mechanisms. Parameters can be supplied either during job definition or trigger creation.
Method 1: Passing Data During Job Creation
Parameters can be attached directly to the job detail when defining the job:
IJobDetail task = JobBuilder.Create<NotificationService>()
.WithIdentity("notificationTask", "primaryGroup")
.WithDescription("Sends periodic notifications")
.Build();
task.JobDataMap.Add("RecipientName", "John Doe");
task.JobDataMap.Add("CurrentYear", DateTime.Now.Year);
With in the job execution method, these values are retrieved from the job's data map:
string recipient = context.JobDetail.JobDataMap.GetString("RecipientName");
Method 2: Attaching Data to Triggers
Alternatively, parameters can be associated with the trigger instead of the job:
ITrigger schedule = TriggerBuilder.Create()
.WithIdentity("notificationTrigger", "primaryGroup")
.WithSimpleSchedule(config => config.WithIntervalInSeconds(5).WithRepeatCount(3))
.Build();
schedule.JobDataMap.Add("TargetYear", DateTime.Now.Year + 1);
Accessing trigger-level parameters follows a similar pattern:
int targetYear = context.Trigger.JobDataMap.GetInt("TargetYear");
Method 3: Using MergedJobDataMap
The MergedJobDataMap provides a unified view combining both job and trigger data maps:
int effectiveYear = context.MergedJobDataMap.GetInt("TargetYear");
When duplicate keys exist between job and trigger data maps, values from the trigger take precedence.
Maintaining State Between Executions
By default, Quartz jobs are stateless. To preserve data across executions, the [PersistJobDataAfterExecution] attribute enables automatic persistence:
[PersistJobDataAfterExecution]
public class NotificationService : IJob
{
public Task Execute(IJobExecutionContext context)
{
int currentYear = context.JobDetail.JobDataMap.GetInt("CurrentYear");
// Process notification logic
// Update the year for next execution
context.JobDetail.JobDataMap.Put("CurrentYear", currentYear + 1);
return Task.CompletedTask;
}
}
Preventing Concurrent Execution
For scenarios where job execution time exceeds the scheduled interval, the [DisallowConcurrentExecution] attribute ensures sequential processing:
[PersistJobDataAfterExecution]
[DisallowConcurrentExecution]
public class NotificationService : IJob
{
// Implementation remains unchanged
}
This prevents overlapping executions and maintains data consistency even when individual job runs exceed their shceduled frequency.