【问题标题】:Quartz.net cron trigger expression for every two weekQuartz.net cron 触发器表达式每两周一次
【发布时间】:2017-12-19 18:46:11
【问题描述】:

我需要创建每两周的星期五运行的 cron 触发器

0 30 17 ? * FRI#2 *

是我设法创建的,但它生成的时间表只是在每月的第二个星期五运行。是否可以使用Cron Expression 实现我所需要的?

我在quartz.net 2.x 中听说了新的触发器类型,但在 XML 配置文件中找不到任何好的示例来配置它。我的意思是 CalendarIntervalTrigger 谁能帮助我获得想要的结果?

更新

            var trigger = TriggerBuilder.Create()
            .WithIdentity("InvoiceGenerator", "InvoiceGenerator")
            .StartNow()
            .WithSchedule(CalendarIntervalScheduleBuilder.Create().WithIntervalInWeeks(2)).Build();

这是我设法在 c# 端创建的(不幸的是没有 xml),但是当我在 trigger 上调用 GetNextFireTimeUtc 时,它总是返回 null。

更新 谢谢大家的回答,我想出的办法是创建每周五运行的正常 cron 触发器,并在执行时检查天气是否超过了科学上次运行的时间。

用c#是下面的代码sn-p。

        var friday = new DateTime(2015, 04, 10, 17, 30, 00);
        var trigger = TriggerBuilder.Create()
                .WithIdentity("InvoiceGenerator", "InvoiceGenerator")
                .WithCalendarIntervalSchedule(x => x.WithIntervalInWeeks(2))
                .WithDescription("trigger")
                .StartAt(friday)
                .Build();
        var nexRun = trigger.GetFireTimeAfter(friday);

nexRun 在这种情况下是正确的。 现在唯一剩下的就是找出我们可以使用 XML 配置它的人。

【问题讨论】:

  • GetNextFireTimeUtc 在第一次触发触发器之前为空

标签: c# xml quartz.net


【解决方案1】:

使用一个触发器以编程方式执行此操作相当简单。我不认为它可以通过单个 cron 表达式来完成。

        var friday = new DateTime(2015, 04, 02, 17, 30, 00)
        var trigger = TriggerBuilder.Create()
                .WithIdentity("InvoiceGenerator", "InvoiceGenerator")
                .WithCalendarIntervalSchedule(x => x.WithIntervalInWeeks(2))
                .WithDescription("trigger")
                .StartAt(friday) 
                .Build();

在我看来,您正在使用 RAMJobStore,在这种情况下,您的触发器保存在quartz_jobs.xml 文件中。在 XML 中设置日历间隔确实是可能。例如,上面的触发器将翻译如下:

<trigger>
  <calendar-interval>
    <name>calendarJobName</name>
    <group>calendarJobGroup</group>
    <description>CalendarTriggerDescription</description>
    <job-name>jobName1</job-name>
    <job-group>jobGroup1</job-group>
    <start-time>2015-04-02T17:30:00.0Z</start-time>
    <end-time>2099-04-02T17:30:00.0Z</end-time>
    <misfire-instruction>SmartPolicy</misfire-instruction>
    <repeat-interval>2</repeat-interval>
    <repeat-interval-unit>Week</repeat-interval-unit>
  </calendar-interval>
</trigger>

【讨论】:

  • 这里唯一的问题是,如果您在调用 GetNextFireTimeUtc() 后编写此代码,则返回始终为空。我不知道为什么我只是简单地创建了控制台应用程序,并且在 main 方法中只是复制并粘贴了此代码,但 GetNextFireTimeUtc() 方法的结果仍然是相同的 null
  • @Rati_Ge 之后调用 GetNextFireTimeUtc()?您需要先安排触发器,然后按照documentation 中的说明调用该方法。
  • 2099-04-02T17:30:00.0Z 是强制性的还是我可以省略这个标签以便它永远运行?
【解决方案2】:

这不能通过 cron 表达式来实现。您可以通过向 Quartz 作业添加三个触发器来接近,尽管它在五个星期五的几个月内无法满足您的要求。

第一个触发器应该在每个月的第一个星期五触发:

0 30 17 ? * FRI#1 *

第二个触发器应该每个月的第三个星期五触发一次

0 30 17 ? * FRI#3 *

需要第三个触发器来处理带有第五个星期五的月份:

0 30 17 ? * FRI#5 *

最后一次触发并不完美,因为下一次运行将在一周后。

或者,您可以创建一个每周触发的 cron 表达式,让 Quartz 作业检查最后一次触发时间,如果最后一次触发时间少于 14 天前,则不执行任何操作。

【讨论】:

  • 你的意思是在执行时检查最后一次触发时间,如果 DateTime.Today() - 最后一次触发时间少于 14 天什么都不做?
  • 是的,这可能是实现这一点的最简单方法,除非您可以让 CalendarIntervalTrigger 正常工作。
  • 目前这对我们来说似乎没问题,非常感谢您能否也提供 CalendarIntervalTrigger 的链接?
  • 我只在 CalendarIntervalTrigger 上找到了这个博客,虽然它没有提供一个实际的例子:jvilalta.blogspot.co.uk/2011/01/…。请注意,最新的 Quartz.net 版本 2.2.3 包含几个针对 CalendarIntervalTrigger 的错误修复,所以如果可以的话,可能值得更新到这个版本。
【解决方案3】:

我通过为一周中的每一天创建多个作业来解决此问题,然后使用 CalendarIntervalScheduleBuilder 设置每周间隔。不过,您必须手动计算下一个开始日期。

例如

For each DayOfWeek in MyDaysOfWeek
    StartDate = GetNextWeekDay(JobStartDate,DayOfWeek)
    Dim Sched = CalendarIntervalScheduleBuilder.Create().WithIntervalInWeeks(Interval).WithMisfireHandlingInstructionDoNothing()

    Dim JobTrigger = TriggerBuilder.Create().WithIdentity(JobTriggerName).
                            StartAt(StartDate).WithSchedule(Sched).EndAt(EndDate).Build()

     'Add to your scheduler here
next

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2016-03-05
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多