18

I have the following code:

 IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            scheduler.Start();
            IJobDetail job = JobBuilder.Create<EmailJob>().StoreDurably().WithIdentity("J_Email", "J_Mailing").Build();         
            ITrigger trigger = TriggerBuilder.Create()
                                .WithIdentity("MailTrigger1", "T_Mail1")
                                .StartNow()                                
                                .WithSimpleSchedule(x => x.WithMisfireHandlingInstructionIgnoreMisfires()
                                    .WithIntervalInSeconds(3)
                                    .RepeatForever())
                                .Build();       


            ITrigger triggernew = TriggerBuilder.Create()
                               .WithIdentity("MailTrigger", "T_Mail")
                               .StartNow()                               
                               .WithSimpleSchedule(x => x.WithMisfireHandlingInstructionIgnoreMisfires()
                                   .WithIntervalInSeconds(5)
                                   .RepeatForever())
                               .Build();        
            scheduler.ScheduleJob(job,triggernew);
            scheduler.ScheduleJob(job,trigger);

I am getting the following exception:

An unhandled exception of type 'Quartz.ObjectAlreadyExistsException' occurred in Quartz.dll

Additional information: Unable to store Job: 'J_Mailing.J_Email', because one already exists with this identification.

But I have been told that you can have multiple triggers of the same JOB. Maybe I am doing something wrong?

walen
  • 7,103
  • 2
  • 37
  • 58
Waqar Ahmed
  • 1,414
  • 2
  • 15
  • 35

1 Answers1

31

Add the Job to the Scheduler.

Then on the creation of the triggers, use ForJob.

The code below is tested.

IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();


//// scheduler.DeleteJob(new JobKey("J_Email"));


IJobDetail job = JobBuilder.Create<MyConcreteJob>().StoreDurably().WithIdentity("J_Email", "J_Mailing").Build();

scheduler.AddJob(job, true /* bool replace */ ); /* Add the given IJob to the Scheduler - with no associated ITrigger.  */


ITrigger triggerOne = TriggerBuilder.Create()
                    .WithIdentity("MailTrigger1", "T_Mail1")
                    .StartNow()
                    .WithSimpleSchedule(x => x.WithMisfireHandlingInstructionIgnoreMisfires()
                        .WithIntervalInSeconds(3)
                        .RepeatForever())
                    .ForJob(job)
                    .Build();


ITrigger triggerTwo = TriggerBuilder.Create()
                   .WithIdentity("MailTrigger", "T_Mail")
                   .StartNow()
                   .WithSimpleSchedule(x => x.WithMisfireHandlingInstructionIgnoreMisfires()
                       .WithIntervalInSeconds(5)
                       .RepeatForever())
                   .ForJob(job)
                   .Build();


scheduler.ScheduleJob(triggerTwo);
scheduler.ScheduleJob(triggerOne);

scheduler.Start();
granadaCoder
  • 26,328
  • 10
  • 113
  • 146
  • "ForJob" will get you there. – granadaCoder Mar 04 '16 at 19:45
  • Thanks - this was extremely useful. – rizan Mar 31 '16 at 21:34
  • Quartz.net saved me from reinventing the wheel. However I have a question regarding the scenario above whereby I want to trigger the same job with different parameters. An example would be every 5 seconds I would a parameter 10 and ever hour I would recon for the hour by passing 60. However I don't ever want two instances of them running. I hope that makes sense. – rizan Mar 31 '16 at 21:38
  • 3
    For the different parameters, see ".UsingJobData("JobDetailParameter001", "Abcd1234") (for the job setup) and then this for reading the value : public virtual void Execute(IJobExecutionContext context) { JobDataMap mergedMap = context.MergedJobDataMap; string myValue = mergedMap.GetString("JobDetailParameter001"); for non-current, research the [DisallowConcurrentExecution] attribute – granadaCoder Apr 04 '16 at 13:03
  • Thanks dude, appreciate your time and effort. – rizan Apr 05 '16 at 19:21
  • 1
    You can also "inject" C# properties (http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/more-about-jobs.html) which makes the code cleaner. E.g. instead of JobDataMap mergedMap = context.MergedJobDataMap; string myValue = mergedMap.GetString("JobDetailParameter001"); you can simply use "JobDetailParameter001" if you define public string JobDetailParameter001 { private get; set; } – Andrei Drynov Jun 02 '16 at 13:32
  • Thanks @AFD. I didn't know that voodoo existed. – granadaCoder Oct 04 '16 at 15:18
  • How many triggers could be added though? In my scenario I could have up to 100 triggers for a job. Would that still work fine? – Mihai Serban Mar 21 '17 at 16:16
  • You can add (experiment with) adding as many as you want. But you increase the odds of "overlapping", perhaps race-conditions... and misfires. See : https://stackoverflow.com/a/43330447/214977 – granadaCoder Mar 11 '22 at 22:02