netcore3.0 IHost 源码解析(二)
上一篇我们分析了IHostBuilder如何创建IHost的,这篇我们具体介绍下IHost的实现类Host
internal class Host : IHost, IAsyncDisposable { private readonly ILogger<Host> _logger; private readonly IHostLifetime _hostLifetime; private readonly ApplicationLifetime _applicationLifetime; private readonly HostOptions _options; private IEnumerable<IHostedService> _hostedServices; public Host( IServiceProvider services, IHostApplicationLifetime applicationLifetime, ILogger<Host> logger, IHostLifetime hostLifetime, IOptions<HostOptions> options) { Services = services ?? throw new ArgumentNullException(nameof(services)); _applicationLifetime = (applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime))) as ApplicationLifetime; _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _hostLifetime = hostLifetime ?? throw new ArgumentNullException(nameof(hostLifetime)); _options = options?.Value ?? throw new ArgumentNullException(nameof(options)); } public IServiceProvider Services { get; } public async Task StartAsync(CancellationToken cancellationToken = default) { _logger.Starting(); using var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping); var combinedCancellationToken = combinedCancellationTokenSource.Token; await _hostLifetime.WaitForStartAsync(combinedCancellationToken); combinedCancellationToken.ThrowIfCancellationRequested(); _hostedServices = Services.GetService<IEnumerable<IHostedService>>(); foreach (var hostedService in _hostedServices) { // Fire IHostedService.Start await hostedService.StartAsync(combinedCancellationToken).ConfigureAwait(false); } // Fire IHostApplicationLifetime.Started _applicationLifetime?.NotifyStarted(); _logger.Started(); } public async Task StopAsync(CancellationToken cancellationToken = default) { _logger.Stopping(); using (var cts = new CancellationTokenSource(_options.ShutdownTimeout)) using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken)) { var token = linkedCts.Token; // Trigger IHostApplicationLifetime.ApplicationStopping _applicationLifetime?.StopApplication(); IList<Exception> exceptions = new List<Exception>(); if (_hostedServices != null) // Started? { foreach (var hostedService in _hostedServices.Reverse()) { token.ThrowIfCancellationRequested(); try { await hostedService.StopAsync(token).ConfigureAwait(false); } catch (Exception ex) { exceptions.Add(ex); } } } token.ThrowIfCancellationRequested(); await _hostLifetime.StopAsync(token); // Fire IHostApplicationLifetime.Stopped _applicationLifetime?.NotifyStopped(); if (exceptions.Count > 0) { var ex = new AggregateException("One or more hosted services failed to stop.", exceptions); _logger.StoppedWithException(ex); throw ex; } } _logger.Stopped(); } public void Dispose() => DisposeAsync().GetAwaiter().GetResult(); public async ValueTask DisposeAsync() { switch (Services) { case IAsyncDisposable asyncDisposable: await asyncDisposable.DisposeAsync(); break; case IDisposable disposable: disposable.Dispose(); break; } } }
Host的构造函数有4个参数IServiceProvider、IHostApplicationLifetime、ILogger<Host>、IHostLifetime、IOptions<HostOptions>
这些都可以从服务容器中解析出来
看下StartAsync方法
这个方法很简单,它会遍历已经注册IHostedService的实例,分别执行其StartAsync方法。