Есть ли способ вручную запустить BackgroundService в Asp. Net core 3.1 - PullRequest
0 голосов
/ 08 апреля 2020

Я знаю до Asp. Net 3.0 (или 3.1), чтобы вручную запустить BackgroundService, мы могли бы извлечь его из IHostedService и изменить регистрацию DI на:

services.AddSingleton<IHostedService, CustomHostedService>();

, а затем вручную запустить запуск службы, введя службу в конструктор и вызвав StartAsync().

Однако я не могу сделать это в Asp . Net Core 3.1. Взглянув на код метода StartAsync(), фоновые службы запускаются до завершения запуска приложения.

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();
}

Какой лучший способ вручную запустить фоновую службу для запуска?

По сути, это мои настройки:

Фоновая служба

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. Спасибо

1 Ответ

0 голосов
/ 08 апреля 2020

Службы Injected Hosted начинаются с приложения и заканчиваются им. Framework не предоставляет вам ручное управление. Там должны быть основные причины для этого, как. Конечно, вы можете реализовать свои собственные решения с потоками, но если ваш wi sh до go включен со встроенными решениями Microsoft, вы можете использовать Фоновая задача в очереди . Вы запустите фоновый сервис с пустой очередью задач. Сервис будет перечислять ваш первый вкус, который будет добавлен в очередь. Вы можете добавить задачу, когда вы будете sh, тогда она будет работать в фоновом режиме.

...