What is JobDataMap?
The JobDataMap can be used to hold any number of (serializable) objects which you wish to have made available to the job instance when it executes. JobDataMap is an implementation of the IDictionary interface, and has some added convenience methods for storing and retrieving data of primitive types.
In my opinion, JobDataMap used to passing data between Quartz.NET host and Job instance?
Here is one sample code describes how to use JobDataMap.
- Create Console Application
- Install Quartz.NET from NuGet package
-
Add logging configuration to App.config as below
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="common"> <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/> </sectionGroup> </configSections> <common> <logging> <factoryAdapter type="Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging"> <arg key="showLogName" value="true"/> <arg key="showDataTime" value="true"/> <arg key="level" value="INFO"/> <arg key="dateTimeFormat" value="HH:mm:ss:fff"/> </factoryAdapter> </logging> </common> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> </configuration>
-
Define simple ColorJob as code below. This job simple reads data from JobDataMap and write to log
[PersistJobDataAfterExecution] [DisallowConcurrentExecution] public class ColorJob : IJob { private static readonly ILog log = LogManager.GetLogger(typeof(ColorJob)); // parameter names specific to this job public const string FavoriteColor = "favorite color"; public const string ExecutionCount = "count"; // Since Quartz will re-instantiate a class every time it // gets executed, members non-static member variables can // not be used to maintain state! private int counter = 1; /// <summary> /// Called by the <see cref="IScheduler" /> when a /// <see cref="ITrigger" /> fires that is associated with /// the <see cref="IJob" />. /// </summary> public virtual void Execute(IJobExecutionContext context) { // This job simply prints out its job name and the // date and time that it is running JobKey jobKey = context.JobDetail.Key; // Grab and print passed parameters JobDataMap data = context.JobDetail.JobDataMap; string favoriteColor = data.GetString(FavoriteColor); int count = data.GetInt(ExecutionCount); log.InfoFormat( "ColorJob: {0} executing at {1}\n favorite color is {2}\n execution count (from job map) is {3}\n execution count (from job member variable) is {4}", jobKey, DateTime.Now.ToString("r"), favoriteColor, count, counter); // increment the count and store it back into the // job map so that job state can be properly maintained count++; data.Put(ExecutionCount, count); // Increment the local member variable // This serves no real purpose since job state can not // be maintained via member variables! counter++; } }
-
Using the job in Program as code below:
ILog log = LogManager.GetLogger(typeof(Program)); // First we must get a reference to a scheduler ISchedulerFactory sf = new StdSchedulerFactory(); IScheduler sched = sf.GetScheduler(); // get a "nice round" time a few seconds in the future.... DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(null, 10); // job1 will only run 5 times (at start time, plus 4 repeats), every 10 seconds IJobDetail job1 = JobBuilder.Create<ColorJob>() .WithIdentity("job1", "group1") .Build(); ISimpleTrigger trigger1 = (ISimpleTrigger)TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .StartAt(startTime) .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).WithRepeatCount(4)) .Build(); // pass initialization parameters into the job job1.JobDataMap.Put(ColorJob.FavoriteColor, "Green"); job1.JobDataMap.Put(ColorJob.ExecutionCount, 1); // schedule the job to run DateTimeOffset scheduleTime1 = sched.ScheduleJob(job1, trigger1); log.Info(string.Format("{0} will run at: {1} and repeat: {2} times, every {3} seconds", job1.Key, scheduleTime1.ToString("r"), trigger1.RepeatCount, trigger1.RepeatInterval.TotalSeconds)); // All of the jobs have been added to the scheduler, but none of the jobs // will run until the scheduler has been started sched.Start(); log.Info("------- Waiting 60 seconds... -------------"); try { // wait five minutes to show jobs Thread.Sleep(300 * 1000); // executing... } catch (ThreadInterruptedException) { } sched.Shutdown(true);
-
The output similar like this
14:29:20:014 [INFO] Quartz.Impl.StdSchedulerFactory - Default Quartz.NET proper ties loaded from embedded resource file 14:29:20:112 [INFO] Quartz.Impl.StdSchedulerFactory - Using default implementat ion for object serializer 14:29:20:174 [INFO] Quartz.Impl.StdSchedulerFactory - Using default implementat ion for ThreadExecutor 14:29:20:202 [INFO] Quartz.Core.SchedulerSignalerImpl - Initialized Scheduler S ignaller of type: Quartz.Core.SchedulerSignalerImpl 14:29:20:203 [INFO] Quartz.Core.QuartzScheduler - Quartz Scheduler v.2.2.4.400 created. 14:29:20:206 [INFO] Quartz.Simpl.RAMJobStore - RAMJobStore initialized. 14:29:20:212 [INFO] Quartz.Core.QuartzScheduler - Scheduler meta-data: Quartz S cheduler (v2.2.4.400) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED' Scheduler class: 'Quartz.Core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool 'Quartz.Simpl.SimpleThreadPool' - with 10 threads. Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistenc e. and is not clustered. 14:29:20:213 [INFO] Quartz.Impl.StdSchedulerFactory - Quartz scheduler 'Default QuartzScheduler' initialized 14:29:20:213 [INFO] Quartz.Impl.StdSchedulerFactory - Quartz scheduler version: 2.2.4.400 14:29:20:260 [INFO] Lesson4.Program - group1.job1 will run at: Wed, 06 Aug 2014 07:29:30 GMT and repeat: 4 times, every 10 seconds 14:29:20:264 [INFO] Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzSchedu ler_$_NON_CLUSTERED started. 14:29:20:266 [INFO] Lesson4.Program - ------- Waiting 60 seconds... ----------- -- 14:29:30:111 [INFO] Lesson4.ColorJob - ColorJob: group1.job1 executing at Wed, 06 Aug 2014 14:29:30 GMT favorite color is Green execution count (from job map) is 1 execution count (from job member variable) is 1 14:29:39:999 [INFO] Lesson4.ColorJob - ColorJob: group1.job1 executing at Wed, 06 Aug 2014 14:29:39 GMT favorite color is Green execution count (from job map) is 2 execution count (from job member variable) is 1 14:29:49:999 [INFO] Lesson4.ColorJob - ColorJob: group1.job1 executing at Wed, 06 Aug 2014 14:29:49 GMT favorite color is Green execution count (from job map) is 3 execution count (from job member variable) is 1 14:29:59:999 [INFO] Lesson4.ColorJob - ColorJob: group1.job1 executing at Wed, 06 Aug 2014 14:29:59 GMT favorite color is Green execution count (from job map) is 4 execution count (from job member variable) is 1 14:30:09:999 [INFO] Lesson4.ColorJob - ColorJob: group1.job1 executing at Wed, 06 Aug 2014 14:30:09 GMT favorite color is Green execution count (from job map) is 5 execution count (from job member variable) is 1 14:34:20:252 [INFO] Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzSchedu ler_$_NON_CLUSTERED shutting down. 14:34:20:257 [INFO] Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzSchedu ler_$_NON_CLUSTERED paused. 14:34:20:653 [INFO] Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzSchedu ler_$_NON_CLUSTERED Shutdown complete. Press any key to continue . . .
Hope this help!