Home > database >  How to trigger hangfire in a class method without sending a request to the trigger it
How to trigger hangfire in a class method without sending a request to the trigger it

Time:12-11

I am used to writing windows services with top-shelf, where the service will be triggered automatically while the windows service is running.

I came across hangfire which I think is cool and gets a lot done out of the box. But the recurring job is not been triggered in a class method.

I want the job to be triggered some mins after application startup.

All the examples I saw have requests sent from the controller to initiate the job.

    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);
        }
    }

I got this startup setting from hangman docs startup.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();

How do I make it to working without sending a request, because this job has to run every 4 days

CodePudding user response:

if you want it to run once on app startup. my suggestion is use IHostedService 'interface'. If you call RecurringJob here, it will work once and will be triggered again at the end of the time you set your job.

example;

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>();

    }
}

CodePudding user response:

So I added this to configure the method in the startup.

// 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();

      }
  • Related