我有一个配置了hangfire(v1.8.7)的asp.net core MVC 8 Web应用程序,可以执行多个作业。有时,作业可能会超出指定时间并触发另一个实例。我的目标是防止 Hangfire 同时启动同一作业的多个实例。
我只有一台服务器正在运行
我尝试使用DisableConcurrentExecution属性,但它不起作用
[DisableConcurrentExecution(timeoutInSeconds: (3600))]
public ActionResult SetScheduledJob_SyncModifiedItemsFromAffiliateBox()
{
RecurringJob.AddOrUpdate("SyncModifiedItemsFromAffiliateBox_OffHours", () =>
SyncModifiedItemsFromAffiliateBoxJob(), Cron.Minutely());
return RedirectToAction("index");
}
public void SyncModifiedItemsFromAffiliateBoxJob()
{
Thread.Sleep(2 * 60 * 1000);
}
这是我的程序.cs代码:
// Add Hangfire services.
builder.Services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(appSettings.GetConnectionString("HangfireConnection")));
// Add the processing server as IHostedService
builder.Services.AddHangfireServer();
app.UseHangfireDashboard();
app.MapHangfireDashboard();
这是适合我的解决方案:
首先,您需要创建此类从数据库获取已注册的作业并将其与正在运行的作业进行比较。
板条箱类 PreventConcurrentExecutionJobFilter:
公共类 PreventConcurrentExecutionJobFilter :JobFilterAttribute、IClientFilter、IServerFilter { }
在类上实现这些方法:
public void OnCreating(CreatingContext filterContext)
{
var jobs = JobStorage.Current.GetMonitoringApi().ProcessingJobs(0, 100);
var methodAlreadyProcessing = jobs.Any(x => x.Value.Job.Method.Name == filterContext.Job.Method.Name);
if (methodAlreadyProcessing)
{
filterContext.Canceled = true;
}
}
public void OnPerformed(PerformedContext filterContext) { }
void IClientFilter.OnCreated(CreatedContext filterContext) { }
void IServerFilter.OnPerforming(PerformingContext filterContext) { }
其次,您需要调用此类作为作业方法的属性:
[PreventConcurrentExecutionJobFilter]
public void SyncModifiedItemsFromAffiliateBoxJob()
{
Thread.Sleep(2 * 60 * 1000);
}