Implementing a Background Task in C# ASP.NET Core

Web applications are usually reactive, which means that they receive requests from outside, process these requests, and return a response. At the same time, most systems need to perform background maintenance tasks or long-running jobs that are not suited for this request-response paradigm. When running ASP.NET core web applications, this can be done using Background Tasks.

Implementing background tasks is simple. First, let’s create an empty ASP.NET core app. In the directory where you want to put the application, run:

> dotnet new web -n AspDotNetCoreBackgroundService
> cd AspDotNetCoreBackgroundService

The background task is implemented in a class that inherits from the abstract BackgroundService. If you want more control you can instead implement the IHostedService interface, which is implemented by BackgroundService. I’m giving this class the (very creative) name MyBackgroundService.cs, which contains the following code:

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace AspDotNetCoreBackgroundService
{
    public class MyBackgroundService : BackgroundService
    {
        private readonly ILogger<MyBackgroundService> _logger;

        public MyBackgroundService(ILogger<MyBackgroundService> logger)
        {
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation($"MyBackgroundService is executing.");
                await Task.Delay(TimeSpan.FromSeconds(5));
            }
            _logger.LogInformation("MyBackgroundService was interrupted.");
        }
    }
}

Now to wire this class to the web app, we need to declare it in the ConfigureServices method of the Startup class:

public void ConfigureServices(IServiceCollection services)
{
    // some code...

    services.AddHostedService<MyBackgroundService>();

    // some more code...
}

The ExecuteAsync method is called by the application just before it starts to receive requests. In this simple example, the task writes to the log every 5 seconds, until it is canceled (which happens when the web app is terminated). One thing to keep in mind is that this task MUST be async (i.e. await when doing blocking operations), otherwise the application will be blocked (you can test this by replacing the await Task.Delay(TimeSpan.FromSeconds(5)); in ExecuteAsync with Task.Delay(TimeSpan.FromSeconds(5)).Wait() an see how the app never fully starts). I would have expected the framework/library to take care of this, but it doesn’t it, so beware.

Now let’s run the app:

> dotnet run
info: AspDotNetCoreBackgroundService.MyBackgroundService[0]
      MyBackgroundService is executing.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\...\AspDotNetCoreBackgroundService
info: AspDotNetCoreBackgroundService.MyBackgroundService[0]
      MyBackgroundService is executing.
info: AspDotNetCoreBackgroundService.MyBackgroundService[0]
      MyBackgroundService is executing.
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: AspDotNetCoreBackgroundService.MyBackgroundService[0]
      MyBackgroundService was interrupted.

Simple and powerful.

As usual, all of the code (which is not much) is located in my GitHub repo. And until next time, happy coding!