5

我尝试了 Quartz.com 的文档并在谷歌上搜索了几个小时……但找不到一篇关于如何获得下一份工作的好文章(这将在未来被解雇)。

我正在使用 CronTrigger 表达式来安排作业,使用 VB.net (winforms)。工作工作正常......但是我希望我的用户看看它什么时候会下一次火。我将 CronExpression 存储在我的数据库中,我可以使用该表达式向我的最终用户显示下一个触发日期/时间吗?或者如果有任何其他可能的方式,请告知(简单的示例)。

谢谢

编辑

以下代码返回下一个作业将在 12 分钟而不是 20 分钟后触发

    Dim exp As CronExpression = New CronExpression("0 0/20 * * * ?")
    Dim nextFire As String = exp.GetNextValidTimeAfter(DateTime.Now)
    MsgBox(nextFire)
4

3 回答 3

6

您可以创建一个新的 JobKey

JobKey jobKey = new JobKey(jobName, groupName);

并使用密钥获取作业详细信息:

var detail = scheduler.GetJobDetail(jobKey);

这是一个简单的功能,可以满足您的需求:

    private DateTime getNextFireTimeForJob(IScheduler scheduler, string jobName, string groupName = "")
    {
        JobKey jobKey = new JobKey(jobName, groupName);
        DateTime nextFireTime = DateTime.MinValue;

        bool isJobExisting = Scheduler.CheckExists(jobKey);
        if (isJobExisting)
        {
            var detail = scheduler.GetJobDetail(jobKey);
            var triggers = scheduler.GetTriggersOfJob(jobKey);

            if (triggers.Count > 0)
            {
                var nextFireTimeUtc = triggers[0].GetNextFireTimeUtc();
                nextFireTime = TimeZone.CurrentTimeZone.ToLocalTime(nextFireTimeUtc.Value.DateTime);
            }
        }

        return (nextFireTime);
    }

仅当每个作业有一个触发器时,它才有效。
如果您的工作中有多个触发器,您可以遍历它们:

foreach (ITrigger trigger in triggers)
{
    Console.WriteLine(jobKey.Name);
    Console.WriteLine(detail.Description);
    Console.WriteLine(trigger.Key.Name);
    Console.WriteLine(trigger.Key.Group);
    Console.WriteLine(trigger.GetType().Name);
    Console.WriteLine(scheduler.GetTriggerState(trigger.Key));
    DateTimeOffset? nextFireTime = trigger.GetNextFireTimeUtc();
    if (nextFireTime.HasValue)
    {
        Console.WriteLine(TimeZone.CurrentTimeZone.ToLocalTime(nextFireTime.Value.DateTime).ToString());
    }
}

或使用 Linq ( System.Linq) :

 var myTrigger = triggers.Where(f => f.Key.Name == "[trigger name]").SingleOrDefault();
于 2012-11-30T10:46:47.653 回答
4

如果您已经知道 cronExpression 那么您可以调用 GetNextValidTimeAfter ,例如

CronExpression exp = new CronExpression("0 0 0/1 1/1 * ? *");
var nextFire = exp.GetNextValidTimeAfter(DateTime.Now);
Console.WriteLine(nextFire);

如果你想要更多的火灾时间,那么

for(int i=0 ; i< 9; i++)
{
    if (nextFire.HasValue)
    {
        nextFire = exp.GetNextValidTimeAfter(nextFire.Value);        
        Console.WriteLine(nextFire);
     }
}

如果您正在寻找一种更通用的方式来显示现有作业的下一次触发时间,那么请查看这个问题的答案,即使您不使用 cron 表达式也可以。这是石英版本 2

Quartz 版本 1 获取作业和触发器信息的方法类似于以下方法。

 public void GetListOfJobs(IScheduler scheduler)
 {
    var query =
        (from groupName in scheduler.JobGroupNames
         from jobName in scheduler.GetJobNames(groupName)
         let triggers = scheduler.GetTriggersOfJob(jobName, groupName)
         select new 
            { 
                groupName, 
                jobName, 
                triggerInfo = (from trigger in triggers select trigger) 
            }
        );

   foreach (var r in query)
   {
       if (r.triggerInfo.Count() == 0)
       {
           var details = String.Format("No triggers found for : Group {0}  Job {1}", r.groupName, r.jobName);
           Console.WriteLine(details);                   
       }

       foreach (var t in r.triggerInfo)
       {
           var details = String.Format("{0,-50} {9} Next Due {1,30:r} Last Run {2,30:r}  Group {3,-30}, Trigger {4,-50} {5,-50} Scheduled from {6:r} Until {7,30:r} {8,30:r} ",
               t.JobName,
               t.GetNextFireTimeUtc().ToLocalTime(), 
               t.GetPreviousFireTimeUtc().ToLocalTime(),
               t.JobGroup, 
               t.Name, 
               t.Description,
               t.StartTimeUtc.ToLocalTime(), 
               t.EndTimeUtc.ToLocalTime(), 
               t.FinalFireTimeUtc.ToLocalTime(),
               ((t.GetNextFireTimeUtc() > DateTime.UtcNow) ? "Active  " : "InActive")
               );

           Console.WriteLine(details);

       }
   }

}

于 2012-11-29T22:27:38.617 回答
0

即使对于超过结束时间的日期,我也遇到了下一个执行时间的问题。以下是我最终在 Quartz 3.0.4 中返回正确结果的实现

internal static DateTime? GetNextFireTimeForJob(IJobExecutionContext context)
        {
            JobKey jobKey = context.JobDetail.Key;
            DateTime? nextFireTime = null;

            var isJobExisting = MyQuartzScheduler.CheckExists(jobKey);
            if (isJobExisting.Result)
            {
                var triggers = MyQuartzScheduler.GetTriggersOfJob(jobKey);

                if (triggers.Result.Count > 0)
                {
                    var nextFireTimeUtc =  triggers.Result.First().GetNextFireTimeUtc();
                    if (nextFireTimeUtc.HasValue)
                    {
                        nextFireTime = TimeZone.CurrentTimeZone.ToLocalTime(nextFireTimeUtc.Value.DateTime);
                    }
                }
            }

            return nextFireTime;
        }
于 2018-05-02T14:20:26.777 回答