如何在类方法中触发hangfire而不向触发它发送请求
Posted
技术标签:
【中文标题】如何在类方法中触发hangfire而不向触发它发送请求【英文标题】:How to trigger hangfire in a class method without sending a request to the trigger it 【发布时间】:2022-01-14 10:40:46 【问题描述】:我习惯用top-shelf写windows服务,windows服务运行时服务会自动触发。
我遇到了hangfire,我认为它很酷,并且开箱即用可以完成很多工作。但是循环作业不是在类方法中触发的。
我希望在应用程序启动几分钟后触发作业。
我看到的所有示例都有从控制器发送的请求以启动作业。
public class ReportJobs
private readonly IBackgroundJobClient _backgroundJobClient;
private readonly IRecurringJobManager _recurringJobManager;
private readonly Report report;
public ReportJobs(Report _report, IBackgroundJobClient backgroundJobClient, IRecurringJobManager recurringJobManager)
_backgroundJobClient = backgroundJobClient;
_recurringJobManager = recurringJobManager;
report = _report;
public async Task<List<Report>> GetReportAsync()
var currentDate = DateTime.Now.ToString("MM-dd-yyyy");
var future18Months = DateTime.Now.AddMonths(18).ToString("MM-dd-yyyy");
var report = await report.GetReports(currentDate, future18Months);
return report;
public void ScheduleReport()
RecurringJob.AddOrUpdate("jobId", () => GetReportAsync(), Cron.Minutely);
我从hangman docs 获得了这个启动设置 启动.cs
// Add Hangfire services.
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(Configuration.GetConnectionString("InfoConnection"), new SqlServerStorageOptions
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
));
// Add the processing server as IHostedService
services.AddHangfireServer();
如何在不发送请求的情况下使其正常工作,因为此作业必须每 4 天运行一次
【问题讨论】:
如果您希望它每 4 天发生一次,然后在应用程序启动时定义一个 recurring job。附带说明:it's difficult to get your ASP.NET app running 24/7 由于应用程序池关闭和空闲超时等原因。我们发现使用 TopShelf 在 Windows 服务中托管 Hangfire 比让作业执行成为 Web 应用程序的一部分要好得多。 【参考方案1】:如果您希望它在应用启动时运行一次。我的建议是使用 IHostedService 'interface'。如果您在此处调用 RecurringJob,它将工作一次,并在您设置工作的时间结束时再次触发。
例子;
public static void Main(string[] args)
var host = CreateHostBuilder(args).Build();
host.Run();
private static IHostBuilder CreateHostBuilder(string[] args)
var hostBuilder = Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => services.AddHostedService<Worker>(); );
return hostBuilder;
public class Worker : IHostedService
private readonly IHostApplicationLifetime _appLifetime;
private readonly IServiceProvider _serviceProdider;
public Worker(IHostApplicationLifetime appLifetime,
IServiceProvider serviceProvider)
_appLifetime = appLifetime;
_serviceProdider = serviceProvider;
public async Task StartAsync(CancellationToken cancellationToken)
_appLifetime.ApplicationStarted.Register(OnStarted);
await Task.CompletedTask;
public async Task StopAsync(CancellationToken cancellationToken)
await Task.CompletedTask;
private void OnStarted()
using var iServiceScope = _serviceProdider.CreateScope();
var layerHangFire = iServiceScope.ServiceProvider.GetRequiredService<IRecurringJobManager>();
【讨论】:
是的,这会起作用。但我已经实现了一些有效的方法【参考方案2】:所以我添加了这个来配置启动中的方法。
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IRecurringJobManager recurringJobs)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Info v1"));
app.UseHangfireDashboard("/hangfire");
recurringJobs.AddOrUpdate("Job", Job.FromExpression<ReportJobs>(x => x.ScheduleReport()), "*/5 * * * *");
app.UseHttpsRedirection();
app.UseStaticFiles();
【讨论】:
以上是关于如何在类方法中触发hangfire而不向触发它发送请求的主要内容,如果未能解决你的问题,请参考以下文章
Hangfire 定时任务设置某个时间区间每隔一定时间触发的Cron表达式