C# Quartz won't fire 2 triggers of the same job

Viewed 32

I'm writing a pretty basic scheduler program (backup service) and I'm using Quartz. The program uses Ini commands with predetermined dates and times (when should it fire).

I have 3 code snippets:

Constructor where I read in when to fire the inis and go through them with a foreach calling the EventTrigger

public Service1()
        {
            InitializeComponent();

            iniCommands = iniReader.Parser(iniReader.Open(PathFinder()), '#');
            scheduler = StdSchedulerFactory.GetDefaultScheduler().Result; //Quartz necessity
            foreach (var item in iniCommands)
            {
                TaskTimer.Task(item);
                EventTrigger(item);
            }
        }

The method within the foreach. This is where I implemented the first important part of Quartz

public void EventTrigger(IniCommand iniCommand)
        {
            IJobDetail job = JobBuilder.Create<ServiceJob>().Build();
            scheduler.Start();
            ITrigger trigger = TriggerBuilder.Create()
            .WithDailyTimeIntervalSchedule
              (s =>
                 s.WithIntervalInHours(iniCommand.Day * 24)
                .OnEveryDay() // <- Not sure if needed
                .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(iniCommand.Hour, iniCommand.Minute))
              )
            .Build();
            scheduler.ScheduleJob(job, trigger);
            iniCommand.Key = job.Key; // helps determining the right ini in the switch-case
        }

This is the class that implements the IJob interface. When the trigger fires for certain inis this is where it passes through. There is a Global.Inis list containing all the inis and it determines via jobkey which ini to handle within the switch-case. Each ini has its own "switcher" by which the code decides the case.

[DisallowConcurrentExecution]
    public class ServiceJob : IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            IniCommand ini = Global.Inis.First(x => x.Key == context.JobDetail.Key);

            switch (ini.Switcher)
            {
                case "delete":
                    Delete.DeleteTemp(ini);
                    break;
                case "backup":
                    BackupModel.Backup(ini);
                    break;
                case "linux":
                    LinuxClient.Copy(ini);
                    break;
            }
            return Task.CompletedTask;
        }
    }

As you can see I have [DisallowConcurrentExecution] added to the class. However whenever there are 2 (or more) inis that go through the same case (e.g. 2 backup inis) only 1 ini executes and the other does nothing. I know by logging that the inis don't get mixed up within the Global.Inis list. Every method within the switch case works perfectly as intended. I've been reading about it for the last week without success.

What am I doing wrong? What's missing? Please let me know what can I do.

1 Answers

I hit the icebreaker today should anyone meet the same or somewhat same problem as mine here's what solved it for me.

I simply relied on System.Threading:

Parallel.ForEach(iniCommands, command =>
            {
                TaskTimer.Task(command);
                Global.Inis.Add(command);
                EventTrigger(command);
            });

Parallel.Foreach starts a new thread everytime you add an inicommand. I'm not clear how optimal it is on the CPU and other resources.

Handle with care.

Related