Class CycleBackgroundService
A Microsoft.Extensions.Hosting.BackgroundService that performs work in fixed-cadence cycles in the background. Derived classes specify how often the cycle runs via CycleCadenceMs and implement the per-cycle work in ExecuteCycleAsync(CancellationToken).
[PublicAPI]
public abstract class CycleBackgroundService : BackgroundService
- Inheritance
-
objectBackgroundServiceCycleBackgroundService
Examples
public sealed class HeartbeatService : CycleBackgroundService
{
protected override int CycleCadenceMs => 5_000;
protected override Task ExecuteCycleAsync(CancellationToken stoppingToken)
{
Console.WriteLine("Still alive!");
return Task.CompletedTask;
}
}
// Registration:
builder.Services.AddHostedService<HeartbeatService>();
Remarks
The service starts and stops with the Microsoft.Extensions.Hosting.IHost, like any other
Microsoft.Extensions.Hosting.IHostedService. Register it with
Microsoft.Extensions.DependencyInjection.ServiceCollectionHostedServiceExtensions
.AddHostedService or one of the multi-interface overloads in
ServiceCollectionExtensions.
The cadence is anchored to a fixed schedule rather than measured from the end of each cycle: each cycle is scheduled CycleCadenceMs milliseconds after the previous scheduled time, regardless of how long the cycle's work takes. Timing uses monotonic System.Diagnostics.Stopwatch timestamps, so it is unaffected by wall-clock changes and cycle duration does not accumulate drift. If a cycle overruns its time slot, subsequent cycles run back-to-back without delay until the schedule catches up.
When the stopping token is signaled during the wait between cycles, the wait ends immediately and the loop exits without starting another cycle. Cancellation that occurs while ExecuteCycleAsync(CancellationToken) is running must be honored by the derived implementation.
Cycles never overlap; the next cycle does not start until the previous one completes. Any unhandled
exception thrown from ExecuteCycleAsync(CancellationToken) stops the service and is handled according to the
host's BackgroundServiceExceptionBehavior (by default, stopping the host). Handle exceptions inside
ExecuteCycleAsync(CancellationToken) if the service should keep cycling after a failure.
Properties
CycleCadenceMs
The time interval in milliseconds at which the service should cycle.
protected abstract int CycleCadenceMs { get; }
Property Value
- int
Remarks
This value is read at the start of each cycle, so a derived class may vary it between cycles. The interval measures the time between scheduled cycle starts, not the gap between the end of one cycle and the start of the next.
Methods
ExecuteAsync(CancellationToken)
Runs the cycle loop: waits until the next scheduled cycle time, then invokes
ExecuteCycleAsync(CancellationToken), repeating until stoppingToken is signaled.
protected override Task ExecuteAsync(CancellationToken stoppingToken)
Parameters
stoppingTokenCancellationTokenTriggered when the host is shutting down or the service is stopped.
Returns
- Task
A System.Threading.Tasks.Task that represents the lifetime of the cycle loop.
Remarks
Derived classes should implement ExecuteCycleAsync(CancellationToken) rather than overriding this method.
ExecuteCycleAsync(CancellationToken)
Performs the work of the service. Called once per cycle.
protected abstract Task ExecuteCycleAsync(CancellationToken stoppingToken)
Parameters
stoppingTokenCancellationTokenTriggered when Microsoft.Extensions.Hosting.IHostedService.StopAsync(System.Threading.CancellationToken) is called. Pass this token to any asynchronous operations performed within the cycle so the service can shut down promptly.
Returns
- Task
A System.Threading.Tasks.Task that represents the work of a single cycle.
Remarks
The next cycle is not started until the returned task completes; cycles never overlap.
Unhandled exceptions thrown from this method stop the cycle loop and are handled according to the host's
HostOptions.BackgroundServiceExceptionBehavior (by default, stopping the host) — catch and handle
(or log) exceptions here if the service should continue cycling after a failure.