Correct way to start a BackgroundService in ASP.NET Core

21,230

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

Share:
21,230
Creyke
Author by

Creyke

Updated on July 09, 2022

Comments

  • Creyke
    Creyke almost 2 years

    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?

  • Cosmin Sontu
    Cosmin Sontu about 5 years
    * to discover all background services to be run, the framework relies on DI and would call servcies.GetServcies<IHostedService>() which yields IEnumerable<IHostedServcie>. This resolves your service if you register via the Interface. .AddHostedService<T>() does exactly that (docs.microsoft.com/en-us/dotnet/api/…)
  • Saher Ahwal
    Saher Ahwal almost 4 years
    what if for test purposes I want to create multiple instances of background services dynamically based on web API call? then can I call StartAsync?