Hangfire Usage

Component: NServiceBus
NuGet Package NServiceBus (7-pre)
This page targets a pre-release version and is subject to change prior to the final release.

This sample illustrates the use of Hangfire to send messages from within an NServiceBus endpoint.

Hangfire - An easy way to perform background processing in .NET and .NET Core applications. Hangfire is an open-source framework that helps you to create, process and manage your background jobs.

The approach used in this sample can mitigate some of the architectural drawbacks of the NServiceBus Scheduler. The NServiceBus scheduler is built on top of the Timeout Manager which leverages the queuing system to trigger scheduled actions. Under heavy load there may be some disparity between the expected time of a scheduled action and execution time due to the delay between timeout messages being generated and processed.

Running the project

  1. Start both the Scheduler and Receiver projects.
  2. At startup Scheduler will schedule sending a message to Receiver every minute.
  3. Receiver will handle the message.

Code Walk-through

Endpoint Helper

This is a helper class used to make the NServiceBus IEndpointInstance available inside Hangfire jobs. In this sample it is implemented as a static property.

public static class EndpointHelper
{
    public static IEndpointInstance Instance { get; set; }
}

Hangfire also supports Dependency Injection (DI) via the JobActivator API for more advanced scenarios.

Configure and start the scheduler

The endpoint is started and the IEndpointInstance is stored in the static endpoint helper.

This sample uses in-memory storage for the jobs. Production scenarios should use more robust alternatives: SqlServer, Msmq or Redis.

Hangfire calls their scheduler a BackgroundJobServer. It is started automatically when an instance of the BackgroundJobServer class is instantiated.

var endpointInstance = await Endpoint.Start(endpointConfiguration)
    .ConfigureAwait(false);

// store the endpointInstance in a static helper class
EndpointHelper.Instance = endpointInstance;

// use in memory storage. Production should use more robust alternatives:
// SqlServer, Msmq, Redis etc
GlobalConfiguration.Configuration.UseMemoryStorage();

// create and start scheduler instance
var scheduler = new BackgroundJobServer();

Job definition

This sample passes in an expression pointing to the static Run method in SendMessageJob.

public static class SendMessageJob
{
    public static Task Run()
    {
        var endpoint = EndpointHelper.Instance;
        return endpoint.Send("Samples.HangfireScheduler.Receiver", new MyMessage());
    }
}

Note that the EndpointHelper is used by the job to get access to the IEndpointInstance .

Schedule a job

Hangfire will accept any lambda expression as a job definition.

The expression is serialized, stored and scheduled for execution by the BackgroundJobServer in Hangfire.

The schedule is set using Cron syntax through the Cron class. In this sample the job gets scheduled to run every minute.

// Tell Hangfire to schedule the job and trigger every minute
RecurringJob.AddOrUpdate("myJob", () => SendMessageJob.Run(), Cron.Minutely);

Cleanup

The Hangfire server should be disposed when the endpoint is shut down.

scheduler.Dispose();
await endpointInstance.Stop()
    .ConfigureAwait(false);

The Hangfire scheduler implements the IDisposable interface. For cleanup purposes, keep a reference to the scheduler instance and call Dispose() at shutdown. Alternatively, use dependency injection and let cleanup be automatically be managed.

Logging

Hangfire uses LibLog. Since LibLog supports the detection and utilization of Serilog, this sample uses the NServiceBus Serilog integration

Log.Logger = new LoggerConfiguration()
    .WriteTo.ColoredConsole()
    .CreateLogger();
LogManager.Use<SerilogFactory>();

LibLog supports many other common logging libraries. Hangfire can also be configured to use a custom logger. See also Adding logging in Hangfire.

Scale Out

Note that in this sample an instance of the Hangfire scheduler is configured to run in every endpoint's instance. If an endpoint is scaled out then the configured jobs will be executed by each of the running instances. A persistent job storage can help to manage the Hangfire scheduler shared state, including jobs, triggers, calendars, etc.

Further information on Hangfire

Related Articles

  • Scheduling
    Schedule a task or an action/lambda, to be executed repeatedly at a given interval.
  • Timeout Manager
    NServiceBus persistent delayed message store.

Last modified