Correct way to start a BackgroundService in ASP.NET Core

Creyke picture Creyke · Oct 19, 2018 · Viewed 18.6k times · Source

I have implemented a BackgroundService in an ASP.NET Core 2.1 application:

public class MyBackgroundService : BackgroundService
{
    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (true)
        {
            await DoSomethingAsync();
            await Task.Delay(10 * 1000);
        }
        return Task.CompletedTask;
    }
}

I have registered it in my ConfigureServices() method:

services.AddSingleton<MyBackgroundService>();

I am currently (reluctantly) starting it by calling (and not awaiting) the StartAsync() method from within the Configure() method:

app.ApplicationServices.GetService<SummaryCache>().StartAsync(new CancellationToken());

What is the best practice method for starting the long running service?

Answer

Cosmin Sontu picture Cosmin Sontu · Feb 4, 2019

Explicitly calling StartAsync is not needed.

Calling

services.AddSingleton<MyBackgroundService>();

won't work since all service implementations are resolved via DI through IHostedService interface. edit: e.g. svcProvider.GetServices<IHostedService>() -> IEnumerable<IHostedService>

You need to call either:

services.AddSingleton<IHostedService, MyBackgroundService>();

or

services.AddHostedService<MyBackgroundService>();

edit: AddHostedService also registers an IHostedService: https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectionhostedserviceextensions.addhostedservice?view=aspnetcore-2.2