【问题标题】:How to trigger hangfire in a class method without sending a request to the trigger it如何在类方法中触发hangfire而不向触发它发送请求
【发布时间】: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 应用程序的一部分要好得多。

标签: c# asp.net-core cron hangfire


【解决方案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();

      }

【讨论】:

    猜你喜欢
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多