Awesome Open Source
Awesome Open Source

Hangfire.RecurringJobExtensions

Official Site NuGet Build status License MIT

This repo is the extension for Hangfire to build RecurringJob automatically. When app start, RecurringJob will be added/updated automatically. There is two ways to build RecurringJob.

  • RecurringJobAttribute attribute
  • Json Configuration

Using RecurringJobAttribute

We can use the attribute RecurringJobAttribute to assign the interface/instance/static method.

public class RecurringJobService
{
    [RecurringJob("*/1 * * * *")]
    [Queue("jobs")]
    public void TestJob1(PerformContext context)
    {
        context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} TestJob1 Running ...");
    }
    [RecurringJob("*/2 * * * *", RecurringJobId = "TestJob2")]
    [Queue("jobs")]
    public void TestJob2(PerformContext context)
    {
        context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} TestJob2 Running ...");
    }
    [RecurringJob("*/2 * * * *", "China Standard Time", "jobs")]
    public void TestJob3(PerformContext context)
    {
        context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} TestJob3 Running ...");
    }
    [RecurringJob("*/5 * * * *", "jobs")]
    public void InstanceTestJob(PerformContext context)
    {
        context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} InstanceTestJob Running ...");
    }

    [RecurringJob("*/6 * * * *", "UTC", "jobs")]
    public static void StaticTestJob(PerformContext context)
    {
        context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} StaticTestJob Running ...");
    }
}

Json Configuration

It is similar to quartz.net, We also define the unified interface IRecurringJob. Recurring jobs must impl the specified interface like this.

[AutomaticRetry(Attempts = 0)]
[DisableConcurrentExecution(90)]
public class LongRunningJob : IRecurringJob
{
    public void Execute(PerformContext context)
    {
        context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} LongRunningJob Running ...");

        var runningTimes = context.GetJobData<int>("RunningTimes");

        context.WriteLine($"get job data parameter-> RunningTimes: {runningTimes}");

        var progressBar = context.WriteProgressBar();

        foreach (var i in Enumerable.Range(1, runningTimes).ToList().WithProgress(progressBar))
        {
            Thread.Sleep(1000);
        }
    }
}

Now we need to provider the json config file to assign the implemented recurring job, the json configuration samples as below.

[{
    "job-name": "My Job1",
    "job-type": "Hangfire.Samples.MyJob1, Hangfire.Samples",
    "cron-expression": "*/1 * * * *",
    "timezone": "China Standard Time",
    "queue": "jobs"
},
{
    "job-name": "My Job2",
    "job-type": "Hangfire.Samples.MyJob2, Hangfire.Samples",
    "cron-expression": "*/5 * * * *",
    "job-data": {
        "IntVal": 1,
        "StringVal": "abcdef",
        "BooleanVal": true,
        "SimpleObject": {
            "Name": "Foo",
            "Age": 100
        }
    }
},
{
    "job-name": "Long Running Job",
    "job-type": "Hangfire.Samples.LongRunningJob, Hangfire.Samples",
    "cron-expression": "*/2 * * * *",
    "job-data": {
        "RunningTimes": 300
    }
}]

The json token description to the configuration is here.

JSON Token Description
job-name [required] The job name to RecurringJob.
job-type [required] The job type while impl the interface IRecurringJob.
cron-expression [required] Cron expressions.
timezone [optional] Default value is TimeZoneInfo.Utc.
queue [optional] The specified queue name , default value is default.
job-data [optional] Similar to the quartz.net JobDataMap, it is can be deserialized to the type Dictionary<string,object>.
enable [optional] Whether the RecurringJob can be added/updated, default value is true, if false RecurringJob will be deleted automatically.

To the json token job-data, we can use extension method to get/set data with specified key from storage which associated with BackgroundJob.Id when recurring job running.

var intVal = context.GetJobData<int>("IntVal");

context.SetJobData("IntVal", ++intVal);

Building RecurringJob

  • Building with CronJob.

In hangfire client, we can use the helper class CronJob to add or update recurringjob automatically.

//Builds within specified interface or class.
CronJob.AddOrUpdate(typeof(RecurringJobService1),typeof(RecurringJobService2));

//Builds by using multiple JSON configuration files.
CronJob.AddOrUpdate("recurringjob1.json","recurringjob2.json");
  • Building with IGlobalConfiguration.

Use IGlobalConfiguration extension method UseRecurringJob to build RecurringJob, in .NET Core's Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
    services.AddHangfire(x =>
    {
        x.UseSqlServerStorage(_config.GetConnectionString("Hangfire"));

        x.UseConsole();

        //using json config file to build RecurringJob automatically.
        x.UseRecurringJob("recurringjob.json");
        //using RecurringJobAttribute to build RecurringJob automatically.
        x.UseRecurringJob(typeof(RecurringJobService));

        x.UseDefaultActivator();
    });
}

For the json configuration file, we can monitor the file change and reload RecurringJob dynamically by passing the parameter reloadOnChange = true.


Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
c-sharp (11,777
quartz (56

Find Open Source By Browsing 7,000 Topics Across 59 Categories