In this lesson, you will learn how to leverage the IHostedService interface to create robust, long-running background tasks that align with the .NET runtime lifecycle.
The Foundation of Background Work
While your real-time hubs handle incoming requests, you often need logic that persists independently of a specific user connection—such as cleaning up expired cache, monitoring system health, or processing internal message queues. IHostedService is the contract the .NET generic host uses to manage these background workers.
To implement it, your class must define two lifecycle methods: StartAsync and StopAsync.
Implementing the Lifecycle
The runtime calls StartAsync when the application host is ready. This is where you initialize your long-running work. Conversely, StopAsync is invoked during graceful shutdown, providing you a window to release resources, signal cancellation to active loops, or finalize pending operations.
public class SystemMonitorService : IHostedService
{
private CancellationTokenSource _cts = new();
public Task StartAsync(CancellationToken cancellationToken)
{
// Kick off your long-running work here without blocking the host
_ = RunMonitoringLoop(_cts.Token);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
// Trigger cancellation to stop background loops cleanly
_cts.Cancel();
return Task.CompletedTask;
}
private async Task RunMonitoringLoop(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
// Perform background logic...
await Task.Delay(5000, token);
}
}
}
Critical Considerations
The IHostedService lifecycle is strictly ordered by the host. When the application starts, it waits for StartAsync to complete before considering the service "ready." Because of this, avoid performing heavy, blocking synchronous work inside these methods. Always leverage CancellationToken—when the host initiates a shutdown, it passes a token to StopAsync to signal that your service must cease operations immediately. If you fail to honor this token or block the thread indefinitely, you may prevent the application from shutting down gracefully, potentially leading to data corruption or zombie processes.
Key Takeaway: IHostedService provides the essential hook into the .NET application lifecycle, allowing you to orchestrate background tasks that start and stop in harmony with the host runtime.