我使用的是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
以返回上一次运行的时间?
5条答案
按热度按时间8wtpewkr1#
为了解决我上面的评论,您可能有不止一种类型的重复运行的作业,但希望检查以前的状态,您可以检查以前的作业信息实际上与这种类型的作业相关,如下所示(虽然这感觉有点黑客/错综复杂)。
如果你要把
PerformContext
传入job方法,那么你可以使用以下代码:ukqbszuj2#
您可以利用您已经声明的事实-“* 不幸的是,LastExecution被设置为当前时间,因为作业数据在执行作业之前已经更新 *"。
作业包含“LastJobId”属性,该属性似乎是一个递增的ID。因此,您应该能够通过递减LastJobId并查询该ID的作业数据来获取“真实的的”上一个作业。
请注意,这是创建的时间,而不是执行的时间。但它可能对您来说足够准确。请记住,当它是您的第一次运行时,边缘情况,因此将没有以前的作业。
nnt7mjpx3#
经过多方研究,我想出了以下解决方案。
它并不完美,但我认为比其他的解决方案干净一点。希望他们能尽快实施一个官方的方式。
dldeef674#
@Marius施泰因巴赫给出的答案通常足够好,但如果你有数千个作业执行(我的例子),从DB加载所有的作业似乎并不那么好。所以最后我决定写一个简单的SQL查询并直接使用它(这是针对PostgreSQL存储的,但将其改为SqlServer应该很简单):
uplii1fm5#
使用此方法返回一个作业的上次执行时间和下次执行时间。此方法返回一个作业的上次执行时间和下次执行时间。