Skip to content

Cancellation

Cancel a run from code using IJobClient:

await client.CancelAsync(runId);

You can also cancel runs from the dashboard by clicking the cancel button on a running or pending job.

Pending runs are cancelled immediately. Running runs receive a cancellation signal via CancellationToken. If a running job doesn’t check its token, it will continue until it finishes or the process shuts down.

When you cancel a run, all of its child runs (triggered via IJobClient from within the job) are also cancelled. This walks the entire trace tree, so grandchildren and deeper descendants are cancelled too.

app.AddJob("Parent", async (IJobClient client, CancellationToken ct) =>
{
// If Parent is cancelled, this child is also cancelled
await client.RunAsync("Child", ct);
});

Set a timeout on a job to automatically cancel it if it runs too long:

app.AddJob("Import", async (CancellationToken ct) =>
{
await LongRunningWork(ct);
})
.WithTimeout(TimeSpan.FromMinutes(5));

Timeout is implemented via cancellation of the running attempt. In run history this appears as cancellation for that attempt.

When the application shuts down, Surefire cancels all running jobs and waits up to ShutdownTimeout (default 15 seconds) for them to finish.

builder.Services.AddSurefire(options =>
{
options.ShutdownTimeout = TimeSpan.FromSeconds(30);
});

Shutdown sends cancellation to running jobs. Whether work is picked up again depends on recovery and retry settings.

The CancellationToken passed to your job delegate is linked to both user cancellation and application shutdown. Use it for any async operations:

app.AddJob("Export", async (CancellationToken ct) =>
{
var data = await db.QueryAsync(ct);
foreach (var batch in data.Chunk(100))
{
ct.ThrowIfCancellationRequested();
await ProcessBatchAsync(batch, ct);
}
});