liveBook · Manning

Background service

As explained in ASP.NET Core in Action, 3e

BackgroundService is a .NET abstract base class that provides a standard implementation pattern for long-running hosted background work.

A background service runs work without interacting with users directly. It can process queued items or repeat a task while an application is running. In ASP.NET Core, BackgroundService is an abstract base class for long-running hosted work: it implements IHostedService so you can focus on the work in ExecuteAsync(). section 34.0 section 34.1.1

Keep an API endpoint fast

Suppose an API returns exchange rates from a third-party service. Instead of making an HTTP call for every request, a background service can periodically fetch fresh rates into a shared cache. The endpoint then reads the cache. Register the typed client, the cache as a singleton, and the service with AddHostedService<ExchangeRatesHostedService>(). section 34.1.1

Figure 34.1 You can use a background task to cache the results from a third-party API on a schedule. The API controller can then read directly from the cache instead of calling the third-party API itself. This reduces the latency of requests to your API controller while ensuring that the data remains fresh.
CH34_F01_Lock3

The diagram shows the division of labor: background updates keep the cache fresh, while API requests read cached results. section 34.1.1

Override ExecuteAsync(CancellationToken stoppingToken) to perform the work. For a repeating task, check stoppingToken.IsCancellationRequested in the loop and pass the token to waits where appropriate. The worker-template example logs the time, waits one second, and repeats until shutdown is requested. section 34.2.1 section 34.4

Listing 34.6 Default BackgroundService implementation for worker service template
public class Worker : BackgroundService                    #1
{
    private readonly ILogger<Worker> _logger;
    public Worker(ILogger<Worker> logger)
    {
        _logger = logger;
    }
 
    protected override async Task ExecuteAsync(            #2
        CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)     #3
        {
            _logger.LogInformation(
                "Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);         #4
        }
    }
}

This small worker makes the repeating pattern concrete: check for cancellation, do the work, then delay with the same token. section 34.2.1

Avoid putting a long-running awaited loop in IHostedService.StartAsync(): startup waits for that method. BackgroundService supplies the long-running pattern through ExecuteAsync(). Delaying startup can be intentional—for example, if initial data must be ready before requests are handled—but it should be a deliberate choice. section 34.1.1

A hosted service is created once, so do not constructor-inject a scoped dependency such as an EF Core DbContext into it. If each update needs scoped services, create an IServiceProvider scope inside the loop, resolve them from that scope, and dispose the scope when the update finishes. section 34.1.2

The same BackgroundService can run in an ASP.NET Core app or a headless worker service. The worker template uses a generic IHost and has no request-handling endpoints. For more complex schedules or coordination across instances, Quartz.NET provides jobs, triggers, and clustering beyond a simple repeating loop. section 34.2.1 section 34.3

How ASP.NET Core in Action, 3e covers it

How deep it goes
Explains ExecuteAsync, startup behavior, cancellation, registration, and scoped dependency handling through working patterns.
Examples
Uses a periodically refreshed exchange-rate cache and a worker that logs once per second.
What it assumes
Assumes familiarity with C# asynchronous methods and introduces the hosted-service pattern through a small application.
What you can do after
Build it from scratch by overriding ExecuteAsync, registering the hosted service, and creating scopes when updates need scoped dependencies.
How it connects
Connects IHostedService and dependency injection to worker services, EF Core, and Quartz.NET scheduling.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.