我正在尝试启动一个间隔任务,每隔x小时运行一次,并从某个时间点开始运行。
目前我的cron看起来像这样。
0 <OffsetMinsAmount>/<Mins Increment> <OffsetHoursAmount>/<Hours Increment> ? * *
eg
0 22/51 3/0 ? * * // starting at 3:22 every 51 mins do x
如果我在3:22之前安排上述示例,它将在3:22工作,然后安排下一次运行时间@ 4 22
这不是我预期的,因为下次应该是4:13
从我在网上阅读的内容来看,我做错了,因为这在一个小时内就是x分钟。
任何人都可以提出我做错的事吗?
这也是我创建它的方式(.net):
trigger = TriggerBuilder.Create()
.WithCronSchedule(cronExpression, x => x.WithMisfireHandlingInstructionDoNothing())
.StartAt(schedulerTask.Start.ToUniversalTime())
.EndAt(null)
.Build();
答案 0 :(得分:1)
这可能已经太晚了,但看起来你试图使用的cron表达式实际上有3个错误的东西。
由于您使用repeatForever()方法解决了问题,因此您可能不需要执行任何操作。使用SimpleSchedule路径我可以看到的唯一缺点是,您正在失去使用纯cron表达式所获得的一点灵活性(即,如果您希望允许用户传入cron表达式)例如,或者如果你想支持其他不了解Quartz但熟悉cron表达式的系统,或者如果你想支持其他系统。这实际上取决于您使用它的用例。无论如何,这是解释:
<强>解释强>
在进入表达式细分之前,有一点需要了解的是Quartz,每当你指定一个时间间隔时,间隔部分将只重复到特定时间值的限制(59秒,秒和分钟,23如果(开始时间+间隔)超过这个限制,它就好像虽然时间不存在(如果你考虑它,它真的没有),所以Quartz会跳过它并继续下一个符合你日程安排的时间间隔而不会过去。即使您没有指定间隔,情况也是如此。
在您的示例22/51
中,您希望从51
分钟开始每隔22
分钟安排一次。但实际上最终发生的事情是,每当分钟标记达到22
而你没有前往13
时,你就安排了一些事情。这是因为开始时间+间隔(22 + 51 = 73
)超过了59
的微小间隔的限制。 Quartz不够聪明,知道它应该包裹着#34;超过59
到下一个小时的额外分钟。
这里还有另一个问题,如果你指定了一个较小的时间间隔,比如说10
,那么你的表达式是22/10
,那么你的日程安排就会执行{ {1}}分钟从分钟10
开始直至22
的分钟限制。因此,如果您希望从59
开始每隔10
分钟运行一次,那么它就不会像您预期的那样在4:22
和4:02
运行。同样,这是由于Quartz处理这个问题的本质。
相反,你应该做的是使用特殊范围字符4:12
来指定你的分钟范围,这将告诉石英你希望它做什么&#34;包裹&#34;对于超过最大值的任何分钟。所以你的分钟表达式实际上应该是-
。这意味着从分钟22-21/51
开始一直到分钟22
(换句话说,距离21
一整小时,然后从22-59
开始)你想要只做每一件事这些合计分钟的0-21
分钟。这实际上可以让您超过51
分钟限制(或您正在使用的任何时间价值)。
<强>实施例强>
官方Quartz documentation实际上有一些例子显示我想要解释的内容。这是一对夫妇:
59
注意如何指定14(2pm)作为起始小时并不意味着它将每小时运行一次。这意味着时间表将从下午2点开始每5分钟运行一次,但绝不会超过2-3pm范围。如果你想每天每小时从下午2点开始每隔5分钟运行一次,那么表达式就是0 0/5 14 * * ? Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day
(0 0/5 14-13 * * ?
表示从小时14-13
开始,然后环绕几小时第二天的14-23
)
0-13
这与上面的示例类似,只是除了从0 0/5 14,18 * * ? Fire every 5 minutes starting at 2pm and ending at 2:55pm, AND fire every 5 minutes starting at 6pm and ending at 6:55pm, every day
运行某些内容之外,他们还使用2-3pm
字符和小时添加了6-7pm
的另一个小时范围价值,
。
不幸的是,文档中的示例有点缺乏,并且没有涵盖Quartz可能遇到的所有不同组合和用例。我发现一个非常有价值的工具可以用Cronmaker来验证你的cron表达式。
<强>击穿强>
以下是对示例cron表达式中的错误的解释:
18
这是表达式的第一个问题。这意味着从22分钟(例如3:22)开始每51分钟一直运行直到该小时的59分钟标记,但它不会像你期望的那样在13分钟的标记处包裹到下一个小时。请参阅上面的冗长解释。
22/51
这是其他两个问题所在。第一个是,与表达式的分钟部分类似,通过单独使用3/0
,您可以说从第3小时开始直到(但不包括)第4小时开始运行。第二个是通过使用3
你实际上告诉它永远不会重复超过3。
<强>解决方案强>
为了实现你想要每天每小时从早上3:22开始每51分钟运行一次的时间表你应该使用它:
/0
小时字段中的0 22-21/51 3-2/1 * * ?
实际上不是必需的,因为默认情况下它会每小时重复一次,但您可以将其保留以明确显示。因此,如果您想:
/1
请注意我如何指定分钟和小时的范围,以确保它们不会执行到特定限制结束时(59分钟和23小时)。
无论如何,我希望如果我的解释有点令人困惑,这会有所帮助。如果不为自己尝试,很难描述并且可能理解这些东西。希望这些例子让它更清晰一点。
答案 1 :(得分:0)
马克先生对这里的钱很感兴趣简单就好了。
下面的工作很好,谢谢你。
int mins;
if (int.TryParse(schedulerTask.Data, out mins) && mins > 0)
{
trigger = TriggerBuilder.Create()
.WithSimpleSchedule(x => x
.WithIntervalInMinutes(mins)
.RepeatForever()
.WithMisfireHandlingInstructionNextWithRemainingCount())
.StartAt(schedulerTask.Start.ToUniversalTime())
.EndAt(null)
.Build();
}