Cron Job 只执行一次?
Cron Job Only Executes Once?
我正在尝试为 Quartz.NET(版本 2.4.1.0)中的 cron 作业创建一个 quartz 调度程序。我有一个工作以指定的时间间隔触发,另一个工作在开始时触发一次并且再也不会触发(它也有一个指定的时间间隔)。
我有点难过,因为这些工作的唯一变化是它们的名称和 CronSchedules(在触发器中找到)。
Note: I have researched similar problems to this online (as well as Stack Overflow) and I have found nothing that solves my problem.
My DB connection works perfectly (UID/PWD left blank in this example).
All Cron Expressions have been tested in CronMaker and are valid.
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>
Program.cs
Note: Job 3 is successfully firing every minute. Job 4 fires once at the start and then stops firing (should be every 30 seconds).
职位:
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());
输出
有什么可能导致这种情况的想法吗?
我没发现代码有什么问题。
我唯一能想到的是,您的 Job 4 以某种方式结束了异常,该异常由 Quartz 静默处理,但阻止它安排下一次执行。
也许可以添加一个 JobListener,看看是否可以使用它来解决正在发生的问题。
我能够查明问题所在。
我没有正确处理数据库中的数据。
在 运行 项目之后,我会先从 QRTZ_TRIGGERS table 中删除所有行,然后从 QRTZ_JOB_DETAILStable。这将允许我 运行 我的项目而不会收到错误:"Unable to Store Job"。我没有意识到 QRTZ_CRON_TRIGGERS table 正在为每个连续的 运行 重复其字段(我是 运行下面是不同的例子):
当我更新 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);
这删除了所有现有数据,并将其替换为我目前正在 运行 的工作中找到的数据。现在我所有的工作都 运行 适当地。
我正在尝试为 Quartz.NET(版本 2.4.1.0)中的 cron 作业创建一个 quartz 调度程序。我有一个工作以指定的时间间隔触发,另一个工作在开始时触发一次并且再也不会触发(它也有一个指定的时间间隔)。
我有点难过,因为这些工作的唯一变化是它们的名称和 CronSchedules(在触发器中找到)。
Note: I have researched similar problems to this online (as well as Stack Overflow) and I have found nothing that solves my problem.
My DB connection works perfectly (UID/PWD left blank in this example).
All Cron Expressions have been tested in CronMaker and are valid.
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>
Program.cs
Note: Job 3 is successfully firing every minute. Job 4 fires once at the start and then stops firing (should be every 30 seconds).
职位:
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());
输出
有什么可能导致这种情况的想法吗?
我没发现代码有什么问题。
我唯一能想到的是,您的 Job 4 以某种方式结束了异常,该异常由 Quartz 静默处理,但阻止它安排下一次执行。
也许可以添加一个 JobListener,看看是否可以使用它来解决正在发生的问题。
我能够查明问题所在。
我没有正确处理数据库中的数据。
在 运行 项目之后,我会先从 QRTZ_TRIGGERS table 中删除所有行,然后从 QRTZ_JOB_DETAILStable。这将允许我 运行 我的项目而不会收到错误:"Unable to Store Job"。我没有意识到 QRTZ_CRON_TRIGGERS table 正在为每个连续的 运行 重复其字段(我是 运行下面是不同的例子):
当我更新 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);
这删除了所有现有数据,并将其替换为我目前正在 运行 的工作中找到的数据。现在我所有的工作都 运行 适当地。