Hangfire获得最后执行时间

时间:2016-02-04 15:04:38

标签: c# asp.net hangfire

我正在使用hangfire 1.5.3。在我的定期工作中,我想调用一个使用自上次运行以来的时间的服务。不幸的是,LastExecution被设置为当前时间,因为在执行作业之前更新了作业数据。

作业

public abstract class RecurringJobBase
{
    protected RecurringJobDto GetJob(string jobId)
    {
        using (var connection = JobStorage.Current.GetConnection())
        {
            return connection.GetRecurringJobs().FirstOrDefault(p => p.Id == jobId);
        }
    }

    protected DateTime GetLastRun(string jobId)
    {
        var job = GetJob(jobId);

        if (job != null && job.LastExecution.HasValue)
        {

            return job.LastExecution.Value.ToLocalTime();
        }

        return DateTime.Today;
    }
}

public class NotifyQueryFilterSubscribersJob : RecurringJobBase
{
    public const string JobId = "NotifyQueryFilterSubscribersJob";
    private readonly IEntityFilterChangeNotificationService _notificationService;

    public NotifyQueryFilterSubscribersJob(IEntityFilterChangeNotificationService notificationService)
    {
        _notificationService = notificationService;
    }

    public void Run()
    {
        var lastRun = GetLastRun(JobId);
        _notificationService.CheckChangesAndSendNotifications(DateTime.Now - lastRun);
    }
}

注册

RecurringJob.AddOrUpdate<NotifyQueryFilterSubscribersJob>(NotifyQueryFilterSubscribersJob.JobId, job => job.Run(), Cron.Minutely, TimeZoneInfo.Local);

我知道,它配置得很细,所以我可以大致计算时间。但是我想要一个独立于配置的实现。所以我的问题是:我如何实现RecurringJobBase.GetLastRun来返回上次运行的时间?

2 个答案:

答案 0 :(得分:1)

你可以利用你已经说过的事实 - “不幸的是,LastExecution设置为当前时间,因为在执行作业之前更新了作业数据”。

该作业包含“LastJobId”属性,该属性似乎是递增的Id。因此,您应该能够通过递减LastJobId并查询该Id的作业数据来获得“真正的”前一个作业。

var currentJob = connection.GetRecurringJobs().FirstOrDefault(p => p.Id == CheckForExpiredPasswordsId);

if (currentJob == null)
{
    return null; // Or whatever suits you
}

var previousJob = connection.GetJobData((Convert.ToInt32(currentJob.LastJobId) - 1).ToString());

return previousJob.CreatedAt;

请注意,这是创建时间,而不是执行时间。但它可能对你来说足够准确。当你第一次跑步时要记住边缘情况,因此以前没有工作。

答案 1 :(得分:0)

要在上面发表我的评论,您可能正在运行一种以上的重复性作业,但想要检查以前的状态,则可以通过以下方法检查以前的作业信息是否确实与此类型的作业相关(尽管感觉如此)有点hacky /令人费解)。

如果要将PerformContext传递给job方法,则可以使用以下方法:

var jobName = performContext.BackgroundJob.Job.ToString();
var currentJobId = int.Parse(performContext.BackgroundJob.Id);
JobData jobFoundInfo = null;

using (var connection = JobStorage.Current.GetConnection()) {
    var decrementId = currentJobId;
    while (decrementId > currentJobId - 50 && decrementId > 1) { // try up to 50 jobs previously
        decrementId--;
        var jobInfo = connection.GetJobData(decrementId.ToString());
        if (jobInfo.Job.ToString().Equals(jobName)) { // **THIS IS THE CHECK**
            jobFoundInfo = jobInfo;
            break;
        }
    }
    if (jobFoundInfo == null) {
       throw new Exception($"Could not find the previous run for job with name {jobName}");
    }
    return jobFoundInfo;
}