17

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?

6
  • @junnas This unfortunately appears out of date (ASP.NET 2.0 preview before BackgroundService was made available) and it doesn't explain how to make a service start without explicitly invoking StartAsync() Commented Oct 19, 2018 at 12:06
  • Would hangfire be an option? hangfire.io Commented Oct 19, 2018 at 12:21
  • I implemented a background service using Steve Gordon's approach that runs on 2.2 preview 2 though? Commented Oct 19, 2018 at 12:28
  • 2
    By default, after registering services.AddSingleton<MyBackgroundService>();, it will start when application start, there is no need to call StartAsync() expecitly from your own code. Commented Oct 22, 2018 at 7:22
  • 3
    Is there any way to stop the background service starting automatically and instead start on demand? Commented Feb 27, 2020 at 9:38

1 Answer 1

29

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://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectionhostedserviceextensions.addhostedservice?view=aspnetcore-2.2

Sign up to request clarification or add additional context in comments.

2 Comments

* 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 (learn.microsoft.com/en-us/dotnet/api/…)
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?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.