首页 > 解决方案 > 在 .net 核心控制台应用程序中开始启动作用域托管服务实例

问题描述

在 .net 核心应用程序中启动多个托管服务的最佳方式是什么?托管服务的数量在运行时会发生变化,并且在启动新的托管服务实例时需要一个参数。我想将它们实现为范围托管服务:

internal interface IScopedProcessingService
{
    Task DoWork(CancellationToken stoppingToken);
}

internal class ScopedProcessingService : IScopedProcessingService
{
    private int executionCount = 0;
    private readonly ILogger _logger;

    public ScopedProcessingService(ILogger<ScopedProcessingService> logger)
    {
        _logger = logger;
    }

    public async Task DoWork(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            executionCount++;

            _logger.LogInformation(
                "Scoped Processing Service is working. Count: {Count}", executionCount);

            await Task.Delay(10000, stoppingToken);
        }
    }
}

--

public class ConsumeScopedServiceHostedService : BackgroundService
{
    private readonly ILogger<ConsumeScopedServiceHostedService> _logger;

    public ConsumeScopedServiceHostedService(IServiceProvider services, 
        ILogger<ConsumeScopedServiceHostedService> logger)
    {
        Services = services;
        _logger = logger;
    }

    public IServiceProvider Services { get; }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service running.");

        await DoWork(stoppingToken);
    }

    private async Task DoWork(CancellationToken stoppingToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is working.");

        using (var scope = Services.CreateScope())
        {
            var scopedProcessingService = 
                scope.ServiceProvider
                    .GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWork(stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is stopping.");

        await Task.CompletedTask;
    }
}

例如,我想启动多个实例,ScopedProcessingService这些实例将处理不同的任务(长时间运行)。

资料来源:https ://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio#sumption-a-scoped-service-in-a -后台任务

标签: c#docker.net-corehosted

解决方案


你能用下面的方法替换你的 DoWork 方法并重试吗

      private async Task DoWork(CancellationToken stoppingToken)
      {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is working.");

        using (var scope = Services.CreateScope())
        {
          var scopedProcessingService =
              scope.ServiceProvider
                  .GetServices<IScopedProcessingService>();
          foreach (var service in scopedProcessingService)
          {
            await scopedProcessingService.DoWork(stoppingToken);
          }
        }
      }

推荐阅读