MNW #014: Running Background Tasks In ASP.NET Core

Dec 03 2022

4 min read

A big thank you to our sponsors who keep this newsletter free to the reader:

QuadSpinner Highlighter is an open-source Visual Studio extension that lets you highlight important objects and arbitrary texts to help you navigate your code more easily.

Sick of staying up late firefighting deployments? Reclaim your nights with a database that keeps your app up even when things go sideways. Outsource hosting to the experts with RavenDB Cloud today so you can sleep well tomorrow.

In this week's newsletter we will talk about running background tasks in ASP.NET Core. After reading this newsletter, you will be able to set up a background task and have it up and running within minutes.

Background tasks are used to offload some work in your application to the background, outside of the normal application flow. A typical example can be asynchronously processing messages from a queue.

I will show you how to create a simple background task that runs once and completes. And you will also see how to configure a continuous background task, that repeats after a specific period.

Background Tasks With IHostedService

You can define a background task by implementing the IHostedService interface. It has only two methods.

Here's what the IHostedService interface looks like:

public interface IHostedService
    Task StartAsync(CancellationToken cancellationToken);

    Task StopAsync(CancellationToken cancellationToken);

All you have to do is implement the StartAsync and StopAsync methods.

Inside of StartAsync you would usually perform the background processing. And inside of StopAsync you would perform any cleanup that is necessary, such as disposing of resources.

To configure the background task you have to call the AddHostedService method:


Calling AddHostedService will configure the background task as a singleton service.

So does dependency injection still work in IHostedService implementations?
Yes, but you can only inject transient or singleton services.

However, I don't like to implement the IHostedService interface myself. I prefer using the BackgroundService class instead.

Background Tasks With BackgroundService

The BackgroundService class already implements the IHostedService interface, and it has an abstract method that you need to override - ExecuteAsync. When you are using the BackgroundService class, you only have to think about the operation you want to implement.

Here's an example background task that runs EF migrations:

public class RunEfMigrationsBackgroundTask : BackgroundService
    private readonly IServiceProvider _serviceProvider;

    public RunEfMigrationsBackgroundTask(IServiceProvider serviceProvider)
        _serviceProvider = serviceProvider;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        using IServiceScope scope = _serviceProvider.CreateScope();

        await using AppDbContext dbContext =

        await dbContext.Database.MigrateAsync(stoppingToken);

The EF DbContext is a scoped service, which we can't inject directly inside of RunEfMigrationsBackgroundTask. We have to inject an instance of IServiceProvider which we can use to create a custom service scope, so that we can resolve the scoped AppDbContext.

I would not recommend running the RunEfMigrationsBackgroundTask in production. EF migrations can easily fail and you'll run into problems. However, I think it's perfectly fine for local development.

Periodic Background Tasks

Sometimes we want run a background task continuously, and have it perform some operation on repeat. For example, we want consume messages from a queue every ten seconds. How do we build this?

Here's an example PeriodicBackgroundTask to get you started:

public class PeriodicBackgroundTask : BackgroundService
    private readonly TimeSpan _period = TimeSpan.FromSeconds(5);
    private readonly ILogger<PeriodicBackgroundTask> _logger;

    public PeriodicBackgroundTask(ILogger<PeriodicBackgroundTask> logger)
        _logger = logger;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        using PeriodicTimer timer = new PeriodicTimer(_period);

        while (!stoppingToken.IsCancellationRequested &&
               await timer.WaitForNextTickAsync(stoppingToken))
            _logger.LogInformation("Executing PeriodicBackgroundTask");

We're using a PeriodicTimer to asynchronously wait for a given period, before executing our background task.

What If You Need A More Robust Solution?

It should be obvious by now that IHostedService is useful when you need simple background tasks that are running while your application is running.

What if you want to have a scheduled background task that runs at 2AM every day?

You can probably build something like this yourself, but there are existing solutions that you should consider first.

Here are two popular solutions for running background tasks that I worked with before:

I also have an example of using Quartz for processing Outbox messages on my YouTube channel that you can take a look at.

Whenever you're ready, there are 3 ways I can help you 🔥

  1. To access all of the source code that I use in my YouTube videos support me on Patreon
  2. For more practical & in-depth coding examples subscribe to my YouTube channel
  3. Promote yourself to 11k+ subscribers by sponsoring this newsletter (booked out 2 months)

Special Offers 📢

About the Newsletter

11k+ subscribers get one tip to improve their software engineering and .NET skills every Saturday morning.

Connect with Me

Join 11,774 .NET engineers getting 1 actionable .NET tip every Saturday

Actionable tips

Easy to implement

5 minute read

Free, forever