有没有一种方法可以每隔几秒钟设置Hangfire重复任务? 我不想使用“Fire and Forget”任务创建另一个“Fire and Forget”任务的解决方案,如果没有,有什么建议的替代方案?
不确定这是从什么时候开始支持的,但我在ASP.NET Core 2.0中尝试了使用Hangfire 1.7.0。以下代码将每20秒安排一个作业:
RecurringJob.AddOrUpdate<SomeJob>(
x => x.DoWork(),
"*/20 * * * * *");
如果我没记错的话,由于Hangfire使用了NCrontab,支持6个令牌(而不是标准的5个令牌),它允许使用具有6个令牌的cron表达式(以秒为粒度而不是分钟)。
Hangfire仪表板还很好地显示了运行之间的小时间间隔:
SchedulePollingInterval
,就像 takaz 指出的那样。 - JohnnyFun虽然Hangfire不允许您为少于一分钟的任务安排计划,但实际上您可以通过使函数递归调用自身来实现这一点;也就是说,假设您希望某个方法每2秒被调用一次,您可以安排一个后台作业,在启动时调用该方法。
BackgroundJob.Schedule(() => PublishMessage(), TimeSpan.FromMilliseconds(2000));
然后在您的PublishMessage方法中完成您的操作,然后安排一个作业来调用相同的方法;
public void PublishMessage()
{
/* do your stuff */
//then schedule a job to exec the same method
BackgroundJob.Schedule(() => PublishMessage(), TimeSpan.FromMilliseconds(2000));
}
另外一个需要覆盖的是默认的SchedulePollingInterval,它是15秒。否则,你的方法只会每隔15秒运行一次。为了这样做,只需在启动时将BackgroundJobServerOptions的实例传递给UseHangfireServer,像这样:
var options = new BackgroundJobServerOptions
{
SchedulePollingInterval = TimeSpan.FromMilliseconds(2000)
};
app.UseHangfireServer(options);
我不知道我的解决方案有多么“万无一失”,但是我用它达到了我的目标,生产中的一切都很“顺利”。
我也需要做同样的事情,但是要求在5秒内完成。默认的调度轮询间隔设置为15秒。因此,需要进行2步操作才能实现5秒间隔的工作。
在Startup.cs文件中
var options = new BackgroundJobServerOptions
{
SchedulePollingInterval = TimeSpan.FromMilliseconds(5000)
};
app.UseHangfireDashboard();
app.UseHangfireServer(options);
您的工作
RecurringJob.AddOrUpdate(() => YourJob(), "*/5 * * * * *");
Hangfire不支持小于一分钟的定期作业间隔。
为什么?想象一下,如果他们允许小于一分钟:比如1秒。那么Hangfire会多频繁地检查数据库中的定期作业呢?这将导致大量的数据库IO。
有关更多信息,请参见Hangfire上的此讨论。
...
new Thread(() =>
{
//loop from {id=1 through 4}
// create job here with {id} in the name at interval of 1 minute
// sleep 15 seconds
//end loop
}).Start();
...
我也遇到了同样的问题,这是我的解决方案:
private void TimingExecuteWrapper(Action action, int sleepSeconds, int intervalSeconds)
{
DateTime beginTime = DateTime.UtcNow, endTime;
var interval = TimeSpan.FromSeconds(intervalSeconds);
while (true)
{
action();
Thread.Sleep(TimeSpan.FromSeconds(sleepSeconds));
endTime = DateTime.UtcNow;
if (endTime - beginTime >= interval)
break;
}
}
intervalSeconds 是最小的 NCRON 时间间隔。它是1分钟。 action 是我们的工作代码。 此外,我建议使用 DisableConcurrentExecution 来避免一些并发冲突。