Using Cancellation Tokens¶
Hangfire provides support for cancellation tokens for our background jobs to let them know when a shutdown request was initiated, or job performance was aborted. In the former case the job will be automatically put back to the beginning of its queue, allowing Hangfire to process it after restart.
We should use cancellation tokens as much as possible – they greatly lower the application shutdown time and the risk of the appearance of the ThreadAbortException
.
CancellationToken¶
Starting from Hangfire 1.7.0 it’s possible to use a regular CancellationToken
class for this purpose. Unlike the previous IJobCancellationToken
-based implementation, the new one is fully asynchronous and doesn’t lead to immediate storage requests so it’s now safe to use it even in tight loops.
public async Task LongRunningMethod(CancellationToken token)
{
for (var i = 0; i < Int32.MaxValue; i++)
{
await Task.Delay(TimeSpan.FromSeconds(1), token);
}
}
When creating such a background job, any CancellationToken
instance can be used, it will be replaced internally just before performing a background job.
BackgroundJob.Enqueue<IService>(x => x.LongRunningMethod(CancellationToken.None));
Dedicated background process is watching for all the current background jobs that have a cancellation token parameter in a method and polls the storage to watch their current states. When state change is detected or when shutdown is requested, the corresponding cancellation token is canceled.
The polling delay is configurable via the BackgroundJobServerOptions.CancellationCheckInterval
server option.
services.AddHangfireServer(new BackgroundJobServerOptions
{
CancellationCheckInterval = TimeSpan.FromSeconds(5) // Default value
});
IJobCancellationToken¶
This is the obsolete implementation of cancellation tokens. Although it’s implemented asynchronously in the same way as CancellationToken
-based one, we can’t use it in many use cases. Backward compatibility is the only reason for using this interface nowadays, so we should prefer to use CancellationToken
parameters in the new logic.
The interface contains the ThrowIfCancellationRequested
method that throws the OperationCanceledException
when cancellation was requested:
public void LongRunningMethod(IJobCancellationToken cancellationToken)
{
for (var i = 0; i < Int32.MaxValue; i++)
{
cancellationToken.ThrowIfCancellationRequested();
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
When we want to enqueue such method call as a background job, we can pass the null
value as an argument for the token parameter, or use the JobCancellationToken.Null
property to tell code readers that we are doing things right:
BackgroundJob.Enqueue(() => LongRunningMethod(JobCancellationToken.Null));
The implementation is resolved automatically
Hangfire takes care of passing a proper non-null instance of IJobCancellationToken
during the job execution at runtime.