在ASP.NET Core中启动BackgroundService的正确方式

15

我已经在一个ASP.NET Core 2.1应用程序中实现了BackgroundService:

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

我已经在我的ConfigureServices()方法中进行了注册:

services.AddSingleton<MyBackgroundService>();

我目前(勉强地)通过在Configure()方法内调用(而不是等待)StartAsync()方法来开始它:

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

如何启动长时间运行的服务的最佳实践方法是什么?


2
请查看Steve Gordon的博客:https://www.stevejgordon.co.uk/asp-net-core-2-ihostedservice - juunas
我使用Steve Gordon的方法实现了一个后台服务,它可以在2.2预览版2上运行。 - juunas
2
默认情况下,在注册了 services.AddSingleton<MyBackgroundService>(); 之后,它会在应用程序启动时自动启动,无需从您自己的代码中显式调用 StartAsync() - Edward
3
有没有办法停止后台服务的自动启动,并改为按需启动? - Simon Gymer
显示剩余2条评论
1个回答

27

不需要显式调用StartAsync。

调用

services.AddSingleton<MyBackgroundService>();

由于所有服务实现都是通过IHostedService接口通过DI解析的,因此这种方法不起作用。 编辑: 例如: svcProvider.GetServices<IHostedService>() -> IEnumerable<IHostedService>

您需要调用以下方法之一:

services.AddSingleton<IHostedService, MyBackgroundService>();
或者
services.AddHostedService<MyBackgroundService>();

编辑: AddHostedService还将注册一个IHostedService:https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectionhostedserviceextensions.addhostedservice?view=aspnetcore-2.2


4
为了发现所有要运行的后台服务,该框架依赖于 DI,并会调用 services.GetServices<IHostedService>() 方法,返回 IEnumerable<IHostedService>。如果您通过接口进行注册,它将解析您的服务。.AddHostedService<T>() 正是这样做的(https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectionhostedserviceextensions.addhostedservice?view=aspnetcore-2.2)。 - Cosmin Sontu
1
如果出于测试目的,我想根据 Web API 调用动态地创建多个后台服务实例,那么我能调用 StartAsync 吗? - Saher Ahwal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接