-1

在 .NET Core 3.1 (Console) 应用程序中,是否可以通过AddHostedService并行添加来启动服务?

实际上我添加的两个服务似乎是在同步模式下启动的(一个接一个)我的代码如下:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host
    .CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((context, confBuilder) =>
    {
        confBuilder
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json")
        .AddEnvironmentVariables();
    })
    .ConfigureServices((hostContext, services) =>
    {
        if (args.Contains(Args.Contoso))
        {
            services.AddHostedService(provider =>
                new ContosoService(
                    provider.GetService<ILogger<ContosoService>>(),
                    provider.GetService<IContosoRepository>(),
                    mode));
        }

        // if there also Alonso in the list, make them run in parallel !
        if (args.Contains(Args.Alonso))
        {
            services.AddHostedService(provider =>
                new AlonsoService(
                    provider.GetService<ILogger<AlonsoService>>(),
                    provider.GetService<IAlonsoRepository>(),
                    mode));
        }
    });

知道这两种服务都是IHostedService

public class AlonsoService : IHostedService {...}
public class ContosoService : IHostedService {...}
4

1 回答 1

2

实际上我添加的两个服务似乎是以同步模式启动的(一个接一个)

按照设计,框架会按照将它们添加到服务集合中的顺序一次一个地等待每个托管服务的启动

源代码

internal class HostedServiceExecutor
{
    private readonly IEnumerable<IHostedService> _services;
    private readonly ILogger<HostedServiceExecutor> _logger;

    public HostedServiceExecutor(ILogger<HostedServiceExecutor> logger, IEnumerable<IHostedService> services)
    {
        _logger = logger;
        _services = services;
    }

    public Task StartAsync(CancellationToken token)
    {
        return ExecuteAsync(service => service.StartAsync(token));
    }

    public Task StopAsync(CancellationToken token)
    {
        return ExecuteAsync(service => service.StopAsync(token), throwOnFirstFailure: false);
    }

    private async Task ExecuteAsync(Func<IHostedService, Task> callback, bool throwOnFirstFailure = true)
    {
        List<Exception>? exceptions = null;

        foreach (var service in _services)
        {
            try
            {
                await callback(service);
            }
            catch (Exception ex)
            {
                if (throwOnFirstFailure)
                {
                    throw;
                }

                if (exceptions == null)
                {
                    exceptions = new List<Exception>();
                }

                exceptions.Add(ex);
            }
        }

        // Throw an aggregate exception if there were any exceptions
        if (exceptions != null)
        {
            throw new AggregateException(exceptions);
        }
    }
}

注意循环中等待的回调

于 2021-01-06T17:33:58.943 回答