• 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方法。

  • 相关阅读:
    虚树入门
    378. 骑士放置(最大独立集)
    377. 泥泞的区域(最大点集)
    352. 闇の連鎖
    P2680 运输计划
    Linux下的段错误(Segmentation fault)
    Acwing 98-分形之城
    快速幂 和 快速乘
    P1308-道路修建 (noi 2011)
    洛谷 P1070 道路游戏(noip 2009 普及组 第四题)
  • 原文地址:https://www.cnblogs.com/lanpingwang/p/12558572.html
Copyright © 2020-2023  润新知