Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
375 views
in Technique[技术] by (71.8m points)

c# - launch AddHostedService services in parallel

In an .NET Core 3.1 (Console) application, is there a way to launch services, added by AddHostedService in parallel?

Actually the two services I add seem to be launched in synchronous mode (one after other) My code is the following:

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

knowing that both services are IHostedService

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Actually the two services I add seem to be launched in synchronous mode (one after other)

By design the framework awaits the start of each hosted service one at a time in the order they were added to the service collection

Source Code

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

note the awaited callback in the loop


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...