如何按需启动 ASP.NET Core BackgroundService?

How to start an ASP.NET Core BackgroundService on demand?

我希望能够在 ASP.NET Core 2.2 中启动即发即弃作业。我尝试了以下方法:

services.AddHostedService<TestHostedService>();


public class TestHostedService : BackgroundService
{
    private readonly ILogger _logger;

    public TestHostedService(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<TestHostedService>();
    }

    public IBackgroundTaskQueue TaskQueue { get; }

    protected async override Task ExecuteAsync(
        CancellationToken cancellationToken)
    {
        _logger.LogInformation("TestHostedService is starting.");

        _logger.LogInformation("TestHostedService is stopping.");
    }
}

但是,这会自动启动,我希望能够按需启动它,类似于 Hangfire 允许的方式:

BackgroundJob.Enqueue<TestJob>(x => x.DoWork());

这也允许作业自然地使用ASP.NET CORE DI。

问题:如何按需启动ASP.NET核心后台服务?


###背景资料

我正在处理一个需要即发即忘各种方法的应用程序。已经编写的代码如下所示:

 Task.Run(() => RunSomething(_serviceScopeFactory));

这意味着每个方法都必须显式地处理获取作用域和检索依赖关系的问题,这非常难看。

如果你想运行MVC控制器或其他服务中的BackgroundService。您可以尝试将 IServiceProvider 注入到那个 class 然后循环所有托管服务并找到后台服务,最后您可以调用 startasync 方法。

更多详情,您可以参考以下代码:

在Startup.cs

中注册服务
        services.AddHostedService<TestHostedService>();

在控制器中执行后台服务:

    public class HomeController : Controller
    {
        private readonly IServiceProvider _serviceProdiver;
        public HomeController(IServiceProvider serviceProdiver) {

            _serviceProdiver = serviceProdiver;

        }

        public async Task<IActionResult> Index()
        {
            
            var allBackgroundServices = _serviceProdiver.GetServices<IHostedService>();
            foreach (var hostedService in allBackgroundServices)
            {
                if (hostedService.GetType() == typeof(TestHostedService))
                {
                    await hostedService.StartAsync(CancellationToken.None);

                }

            }

            return View();
        }
 }

结果: