zoukankan      html  css  js  c++  java
  • 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方法。

  • 相关阅读:
    谈谈软件的开发及成长历程
    Winform开发框架之简易工作流设计
    如何快速开发树形列表和分页查询整合的WInform程序界面
    邮件代收代发功能模块的操作界面设计和阶段性总结
    基于Lumisoft.NET组件的SMTP账号登陆检测
    Winform开发的界面处理优化
    基于DevExpress开发的GridView如何实现一列显示不同的控件类型
    Winform里面的缓存使用
    分享一个Winform里面的HTML编辑控件Zeta HTML Edit Control,汉化附源码
    算法 dfs —— 将二叉树 先序遍历 转为 链表
  • 原文地址:https://www.cnblogs.com/lanpingwang/p/12558572.html
Copyright © 2011-2022 走看看