有没有一种方法可以在Asp.Net Core 3.1中手动启动BackgroundService [英] Is there a way to manually start BackgroundService in Asp.Net core 3.1

查看:937
本文介绍了有没有一种方法可以在Asp.Net Core 3.1中手动启动BackgroundService的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在Asp.Net 3.0(或3.1)之前,要手动启动BackgroundService,我们可以改为从IHostedService派生它,并将DI注册更改为:

I know prior to Asp.Net 3.0 (or 3.1), to manually start a BackgroundService, we could derive it from IHostedService instead and change the DI registration to:

services.AddSingleton<IHostedService, CustomHostedService>();

,然后通过将服务注入构造函数中并调用StartAsync()来手动触发服务启动.

and then manually trigger the service start by injecting the service in the constructor, and calling StartAsync().

但是,我似乎无法在Asp.Net Core 3.1中做到这一点.看一下StartAsync()方法的代码,在应用程序启动完成之前启动了后台服务.

However, I can't seem to do that in Asp.Net Core 3.1. Having a look at the code for the StartAsync() method, background services are started before the app startup is completed.

public async Task StartAsync(CancellationToken cancellationToken = default)
{
    _logger.Starting();
    await _hostLifetime.WaitForStartAsync(cancellationToken);

    cancellationToken.ThrowIfCancellationRequested();
    _hostedServices = Services.GetService<IEnumerable<IHostedService>>();

    foreach (var hostedService in _hostedServices)
    {
        // Fire IHostedService.Start
        await hostedService.StartAsync(cancellationToken).ConfigureAwait(false);
    }

    // Fire IApplicationLifetime.Started
    _applicationLifetime?.NotifyStarted();

    _logger.Started();
}

手动触发后台服务启动的最佳方法是什么?

What's the best way to manually trigger a background service to start?

基本上,这是我的设置:

Essentially, this is my setup:

后台服务

public MyBackgroundService(Func<string, IConsumer> consumerFactory)
{
    _consumerFactory = consumerFactory ?? throw new ArgumentNullException(nameof(consumerFactory));
}

消费品工厂注册

services.AddSingleton<Func<string, IConsumer>>(provider => providerName => provider.ConfigureConsumer(environment, providerName));

private static IConsumer ConfigureConsumer(this IServiceProvider provider, IHostEnvironment environment, string provideName)
{
    if (string.IsNullOrEmpty(provideName))
        throw new ArgumentNullException(nameof(provideName));

    var options = provider.GetRequiredService<IOptions<ConsumerConfig>>();
    if (options?.Value == null)
        throw new ArgumentNullException(nameof(options));

    return environment.IsDevelopment() 
        ? new Consumer(options, provider.GetTopics()) 
        : new Consumer((IOptions<ConsumerConfig>)options.SetSecurityOptions(provider), provider.GetTopics());
}

private static IOptions<Config> SetSecurityOptions(this IOptions<Config> config, IServiceProvider provider)
{
    var certService = provider.GetRequiredService<IVaultCertificateService>();
    ...
    return config;
}

基本上,此 certService 属性仅在请求进入并执行中间件时设置.而且由于当后台服务中的ExecuteAsync()尝试从工厂获取使用者的实例时,无论如何都会执行,所以我没有正确配置IConsumer 谢谢

Essentially this certService properties are only set when a request comes in and executes a middleware. And since when ExecuteAsync() in the background service tries to get an instance of consumer from the factory, is executed regardless, I dont have the IConsumer properly configured Thanks

推荐答案

已注入托管服务以app开始,并以app停止. Framework无法为您提供手动控制.应该有类似的潜在原因.当然,您可以使用线程来实现自己的解决方案,但是如果您希望继续使用Microsoft的内置解决方案,则可以使用

Injected Hosted services starts with app and stops with it. Framework doesn't provide you manual control. There should be underlying reasons for that like . Of course you can implement your own solutions with threads but if your wish to go on with microsoft's built in solutions you can use Queued Background Task. You will start a background service with empty task queue. Service will be listining your first tast to be added to queue. You can add task whenever you wish then it will be running be background.

这篇关于有没有一种方法可以在Asp.Net Core 3.1中手动启动BackgroundService的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆