我试过Quartz.com文档&谷歌搜索了几个小时...但找不到一篇关于如何获得下一个工作的好文章(将来可以解雇)。
我正在使用CronTrigger Expression来安排作业,使用VB.net(winforms)。工作正常...但我希望我的用户看到它下一次火灾。我在我的数据库中存储CronExpression,我可以使用该Expression向我的最终用户显示下一个Fire Date / Time 吗?或者如果有其他可能的方法,请提供建议(简单明了)。
由于
修改
以下代码返回下一个作业将在12分钟而不是20分钟后启动
Dim exp As CronExpression = New CronExpression("0 0/20 * * * ?")
Dim nextFire As String = exp.GetNextValidTimeAfter(DateTime.Now)
MsgBox(nextFire)
答案 0 :(得分:5)
您可以创建一个新的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();
答案 1 :(得分: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);
}
}
如果您正在寻找一种更为一般的方式来显示现有作业的下一次开火时间,那么请查看this问题的答案,即使您没有使用cron表达式也是如此。这适用于Quartz Version 2
获取作业和触发器信息的Quartz Version 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);
}
}
}
答案 2 :(得分: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;
}