使用石英调度器(cron)如何设置偏移基准时间?

使用石英调度器(cron)如何设置偏移基准时间?,cron,quartz.net,Cron,Quartz.net,我正在尝试从一个时间点开始,每隔x小时和y分钟运行一次间隔任务 目前我的cron看起来像这样 0 <OffsetMinsAmount>/<Mins Increment> <OffsetHoursAmount>/<Hours Increment> ? * * eg 0 22/51 3/0 ? * * // starting at 3:22 every 51 mins do x 马科先生在这里赚了很多钱,简单更好 下面的工

我正在尝试从一个时间点开始,每隔x小时和y分钟运行一次间隔任务

目前我的cron看起来像这样

    0 <OffsetMinsAmount>/<Mins Increment> <OffsetHoursAmount>/<Hours Increment> ? * *

    eg

    0 22/51 3/0 ? * * // starting at 3:22 every 51 mins do x

马科先生在这里赚了很多钱,简单更好

下面的工作很好,谢谢你

   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();
   }

这可能已经太晚了,但看起来您尝试使用的cron表达式实际上有三个方面出了问题

由于使用repeatForever()方法解决了问题,因此可能不需要执行任何操作。使用SimpleSchedule路由的唯一缺点是,您正在失去使用纯cron表达式所获得的一点灵活性(例如,如果您希望允许用户直接传入cron表达式,或者如果您希望支持不懂Quartz但熟悉cron表达式的其他系统)。这实际上取决于您使用它的用例。无论如何,下面是解释:

解释

在对表达式进行细分之前,关于Quartz需要了解的一件事是,无论何时指定时间间隔,间隔部分都只会重复到特定时间值的限制(59秒和分钟,23小时,31天),而不会环绕到下一分钟、小时、天等。如果(开始时间+间隔)超过此限制,就好像时间不存在(如果你仔细想想,它实际上不存在),因此Quartz跳过它,继续到下一个符合你计划的间隔,而不重复。即使你没有指定间隔,情况也是如此

在您的示例中,
22/51
,您希望从分钟开始,每
51
分钟安排一件事。但实际发生的情况是,每次分钟标记到达
22
时,您都安排了一件事,而从未转到
13
。这是因为开始时间+间隔(
22+51=73
)超过了分钟间隔的限制,即
59
。Quartz不够聪明,不知道它应该“环绕”过去
59
到下一个小时的额外分钟

这里还有另一个问题,那就是如果你指定了一个更小的时间间隔,比如说
10
,那么你的表达式是
22/10
,那么你的计划将从
22
分钟开始,每
10
分钟执行一次,直到
59
分钟限制。所以如果你想每分钟运行一次
10
分钟从
4:22
开始,那么它就不会像您预期的那样在
4:02
4:12
运行。同样,这是由于Quartz处理此问题的本质

相反,您应该使用特殊范围字符
-
来指定分钟范围,这将告诉quartz您希望它进行“换行”对于超过最大值的任何分钟。因此,你的分钟表达式实际上应该是
22-21/51
。这意味着从
22
分钟开始一直到
21
(换句话说,从
22-59
0-21
,一个小时)您只想在这些组合分钟中每隔
51
分钟做一件事。这实际上会让您超过
59
分钟限制(或您使用的任何时间值)

示例

这位官员实际上有一些例子说明了我试图解释的内容。以下是几个例子:

0 0/5 14 * * ?     Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day
注意如何指定14(下午2点)因为开始时间并不意味着它将每小时运行一次。它的意思是计划将从下午2点开始每5分钟运行一次,但它永远不会超过下午2点到3点的范围。如果您想从每天的每小时下午2点开始每5分钟运行一次,那么表达式将是
0 0/5 14-13**?
14-13
表示从小时数
14-23
到第二天的小时数
0-13

这与上面的示例类似,除了从
2-3pm
运行之外,他们还使用
字符以及小时值
18
添加了另一个小时范围,从
6-7pm

不幸的是,文档中的示例有点缺乏,并且没有涵盖使用Quartz时可能遇到的所有不同组合和用例。我发现一个非常有价值的工具,可以用来验证cron表达式

细分

下面是对示例cron表达式中错误的解释:

22/51
这是表达式的第一个问题。这意味着从22分钟(例如3:22)开始每51分钟运行一次,直到该小时的59分钟标记,但不会像您预期的那样在13分钟标记结束到下一个小时。请参阅上面的详细解释

3/0 
这就是其他两个问题的所在。第一个问题是,与表达式的分钟部分类似,单独使用
3
表示从第3小时开始运行直到(但不包括)第4小时。第二个问题是,使用
/0
实际上是告诉它不要超过3小时重复

解决方案

为了实现您希望从每天凌晨3:22开始每51分钟运行一次的计划,您应该使用以下方法:

0 22-21/51 3-2/1 * * ?
小时字段中的
/1
实际上是不必要的,因为默认情况下,它将每小时重复一次,但您可以将其保留为显式显示。因此,如果您想:

0 22-21/51 3-2 * * ?
请注意,我是如何指定分钟和小时的范围的,以确保它们不会只执行到特定限制的结束(5)
0 22-21/51 3-2/1 * * ?
0 22-21/51 3-2 * * ?