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.
Running the project
- Start both the Scheduler and Receiver projects.
- At startup, Scheduler will schedule sending a message to Receiver every minute.
- Receiver will handle the message.
Code Walk-through
Endpoint Helper
This is a helper class used to make the NServiceBus IMessageSession available inside Hangfire jobs. In this sample it is implemented as a static property.
public static class EndpointHelper
{
public static IMessageSession MessageSession { 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 IMessageSession is stored in the static endpoint helper.
This sample uses in-memory storage for the jobs. Production scenarios should use more robust alternatives: e.g. SQL Server or Redis.
Hangfire calls their scheduler a BackgroundJobServer. It is started automatically when an instance of the BackgroundJobServer class is instantiated.
var builder = Host.CreateApplicationBuilder();
builder.Services.AddNServiceBusEndpoint(endpointConfiguration);
using var host = builder.Build();
var messageSession = host.Services.GetRequiredService<IMessageSession>();
await host.StartAsync();
// store the endpointInstance in a static helper class
EndpointHelper.MessageSession = messageSession;
// use in memory storage. Production should use more robust alternatives:
// SqlServer, Redis etc
GlobalConfiguration.Configuration.UseMemoryStorage();
GlobalConfiguration.Configuration.UseColouredConsoleLogProvider();
// 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 messageSession = EndpointHelper.MessageSession;
return messageSession.Send("Samples.HangfireScheduler.Receiver", new MyMessage());
}
}
Note that the EndpointHelper is used by the job to get access to the IMessageSession .
Schedule a job
Hangfire accepts 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 host.StopAsync();
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.
Scale Out
Note that in this sample, an instance of the Hangfire scheduler is configured to run in every endpoint 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.