【问题标题】:Cron Job Only Executes Once?Cron 作业只执行一次?
【发布时间】:2017-01-28 04:57:23
【问题描述】:

我正在尝试为 Quartz.NET(版本 2.4.1.0)中的 cron 作业创建一个石英调度程序。我有一个以指定间隔触发的作业,另一个在开始时触发一次并且不再触发(它也有指定的间隔)。
我有点难过,因为这些工作的唯一变化是他们的名字和 CronSchedules(在触发器中找到)。

注意:我在网上研究过与此类似的问题(以及 Stack Overflow),但没有发现任何可以解决我的问题的问题。
我的数据库连接工作正常(本例中 UID/PWD 留空)。
所有的 Cron 表达式都在 CronMaker 中测试过并且是有效的。

App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  </configSections>
  <quartz>
    <add key="quartz.scheduler.instanceName" value ="MyScheduler"/>
    <!--5 is recommended for under 100 jobs-->
    <add key="quartz.threadPool.threadCount" value ="5"/>
    <add key="quartz.jobStore.useProperties" value =" false"/>
    <add key="quartz.jobStore.clustered" value ="false"/>
    <add key="quartz.jobStore.misfireThreshold" value ="60000"/>
    <add key="quartz.jobStore.type" value ="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"/>
    <add key="quartz.jobStore.driverDelegateType" value ="Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz"/>
    <add key="quartz.jobStore.tablePrefix" value ="QRTZ_"/>
    <add key="quartz.jobStore.dataSource" value ="myDS"/>
    <!--DB CONNECTION-->
    <add key="quartz.dataSource.myDS.connectionString" value ="Server=localhost;Database=QUARTZ;Uid=;Pwd="/>
    <add key="quartz.dataSource.myDS.provider" value ="SqlServer-20"/>
  </quartz>
</configuration>

程序.cs

注意: Job 3 每分钟成功触发一次。作业 4 在开始时触发一次,然后停止触发(应该每 30 秒一次)。

工作:

public class Job3 : IJob
        {
            public void Execute(IJobExecutionContext context)
            {
                Console.WriteLine("Job 3");
            }
        }

public class Job4 : IJob
        {
            public void Execute(IJobExecutionContext context)
            {
                Console.WriteLine("Job 4");
            }
        }

工作详情:

IJobDetail jdJob3 = JobBuilder.Create<Job3>()
                        .WithIdentity("job3", "group3")
                        .WithDescription("CRON TRIGGER - Job meant to run constantly at 1min intervals")
                        .StoreDurably(true)
                        .Build();

IJobDetail jdJob4 = JobBuilder.Create<Job4>()
                        .WithIdentity("job4", "group3")
                        .WithDescription("CRON TRIGGER - Job meant to run constantly at 30sec intervals")
                        .StoreDurably(true)
                        .Build();

触发器:

//Day Of Month - fires every minute
ITrigger tChron2 = TriggerBuilder.Create()
     .WithIdentity("myTrigger3", "group3")
     .WithCronSchedule("0 0/1 * * * ?", x => x
          .InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time"))
          .WithMisfireHandlingInstructionFireAndProceed()) //handle misfire
      .ForJob("job3", "group3")
      .Build();

//Day Of Month - fires every 30sec, between 8am and 2pm, on the 26th of every month, any year
ITrigger tChron3 = TriggerBuilder.Create()
     .WithIdentity("myTrigger4", "group3")
     .WithCronSchedule("0,30 * 8-14 26 * ?", x => x
          .InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time"))
          .WithMisfireHandlingInstructionFireAndProceed()) //handle misfire
     .ForJob("job4", "group3")
     .Build();

作业监听器:

public class MyJobListener : IJobListener
    {
        void IJobListener.JobExecutionVetoed(IJobExecutionContext context)
        {
            throw new NotImplementedException();
        }

        void IJobListener.JobToBeExecuted(IJobExecutionContext context)
        {
            Console.WriteLine("\r\nJob is about to be executed...");
        }

        void IJobListener.JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException)
        {
            Console.WriteLine("Job was executed...");
        }

        public string Name { get; set; }
    }

//IMPLEMENTATION    
MyJobListener myJobListener = new MyJobListener();
myJobListener.Name = "MyJobListener1";
scheduler.ListenerManager.AddJobListener(myJobListener, GroupMatcher<JobKey>.AnyGroup());

输出

有什么可能导致这种情况的想法吗?

【问题讨论】:

  • 如果使用与 job3 相同的 cron 计划会发生什么?
  • @Set 这就是我确定下面答案中列出的问题的方式。它仍然会以相同的方式运行。

标签: c# cron quartz.net


【解决方案1】:

我找不到代码有什么问题。

我能想到的唯一一件事是,您的 Job 4 以某种方式结束了一个异常,该异常由 Quartz 静默处理,但阻止它安排下一次执行。

也许添加一个 JobListener 并查看是否可以使用它来解决正在发生的事情。

【讨论】:

  • 在上面添加了我的工作监听器。我正在处理 JobExecutionVetoed,但我仍然遇到同样的问题。
  • 可以添加输出吗?
  • 刚刚添加了输出
  • 这个问题是有道理的,找到它的荣誉。
  • 感谢您提供有关使用作业侦听器的指针。这是帮助我调试问题的一部分。
【解决方案2】:

我能够查明问题所在。
我没有正确处理数据库中的数据。

运行项目后,我会先从 QRTZ_TRIGGERS 表中删除所有行,然后再从 QRTZ_JOB_DETAILS 表中删除所有行。这将允许我运行我的项目而不会收到错误:“无法存储作业”。我没有意识到 QRTZ_CRON_TRIGGERS 表在每次连续运行时都会复制其字段(我在下面运行不同的示例):

当我更新 cron 表达式时,这会导致冲突,因为存在相同计划的多个实例。

为了解决这个问题,我使用了“ScheduleJobs”并将替换值设置为 true:

//JOB SCHEDULE CREATOR    
private static void JSCreator(IScheduler scheduler, IJobDetail jdJob, ITrigger tTrig)
            {
                var SJ = new Dictionary<IJobDetail, Quartz.Collection.ISet<ITrigger>>();
                SJ.Add(jdJob, new Quartz.Collection.HashSet<ITrigger>() { tTrig });
                scheduler.ScheduleJobs(SJ, true);
            }


 //IMPLEMENTATION
 JSCreator(scheduler, jdJob1, tSimple1);
 JSCreator(scheduler, jdJob2, tCron1);
 JSCreator(scheduler, jdJob3, tCron2);
 JSCreator(scheduler, jdJob4, tCron3);
 JSCreator(scheduler, jdJob5, tCron4);
 JSCreator(scheduler, jdJob6, tCron5);

这删除了所有现有数据,并将其替换为在我当前运行的作业中找到的数据。现在我所有的工作都在正常运行。

【讨论】:

    猜你喜欢
    • 2011-06-20
    • 2019-03-07
    • 2016-04-15
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多