.NET Core核心组件Hosting实践

ASP.NET Core 是一个跨平台的高性能开源框架,用于生成启用云且连接 Internet 的新式应用。ASP.NET Core应用本质上是一个服务,这个服务启动了一个网络监听器,这个监听器需要长时间的运行。当这个监听器接收到一个HTTP请求之后,监听器会将这个请求传递给管道进行处理。完成处理后就会生成相应的HTTP响应,通过这个监听器返回给客户端。那么长时间运行的服务器需要寄宿在托管服务进程中,提供功能的组件称之为Hosting,也称托管服务。.

    任何在后台长时间运行的服务都可以定义标准的托管服务,寄宿在hosting,接下来我们定义一个托管服务并寄宿在hosting。

实例

    需求是我们设计一个模拟检测服务器cup,内存和硬盘使用率的服务,并寄宿在hosting,可以用配置文件appsettings.json中的属性动态控制监测时间间隔。具体看代码,大家可以把代码拷到vs试一试。

首先建一个cup,内存和硬盘使用率的接口和实现

    public class Sample    {        //首先分别建3个接口        /// <summary>        /// cpu        /// </summary>        public interface ICupCollector        {            int Get();        }
        /// <summary>        /// RAM(内存)        /// </summary>        public interface IRAMCollector        {            int Get();        }
        /// <summary>        /// IO(磁盘读写)        /// </summary>        public interface IIOCollector        {            int Get();        }
        //我们实现接口,用Random模拟数字        public class Collector : ICupCollector, IRAMCollector, IIOCollector        {            int ICupCollector.Get()            {                var random = new Random();                return random.Next(0, 100);            }
            int IRAMCollector.Get()            {                var random = new Random();                return random.Next(0, 100);            }
            int IIOCollector.Get()            {                var random = new Random();                return random.Next(0, 100);            }        }

新建一个记录时间间隔的属性

        //新建一个记录时间间隔的属性        public class AirEnvironmentOptions        {            public long Interval { get; set; }        }

新建一个发布订阅

 public class AirEnvironmentPublisher        {            private const string Template = "CUP资源占比:{CUP, -10}" +                                             "内存资源占比:{ARM, -10}" +                                             "OI资源占比:{IO, -10}" +                                             "时间:{now}";            private readonly Action<ILogger, int, int, int, string, Exception> _logAction;            private readonly ILogger _logger;
            public AirEnvironmentPublisher(ILogger<AirEnvironmentPublisher> logger)            {                _logger = logger;                //日志发布                _logAction = LoggerMessage.Define<int, int, int, string>(LogLevel.Information, 0, Template);            }            //发布器进行输入            public void Publish(int cup, int arm, int io)            {                _logAction(_logger, cup, arm, io, DateTime.Now.ToLongTimeString(), null);            }        }

定义一个Hosting托管服务类

 //定义一个Hosting托管服务类        public class AirEnvironmentService : IHostedService        {            private readonly ICupCollector _cupCollector;            private readonly IRAMCollector _ramCollector;            private readonly IIOCollector _ioCollector;            private readonly AirEnvironmentPublisher _publisher;            private readonly AirEnvironmentOptions _options;
            //新建一个Timer控件定时            private Timer _timer;
            public AirEnvironmentService(                ICupCollector CupCollector,                IRAMCollector RAMCollector,                IIOCollector IOCollector,                AirEnvironmentPublisher publisher,                IOptions<AirEnvironmentOptions> options)            {                _cupCollector = CupCollector;                _ramCollector = RAMCollector;                _ioCollector = IOCollector;                _publisher = publisher;                _options = options.Value;            }            //定时订阅开始            public Task StartAsync(CancellationToken cancellationToken)            {                _timer = new Timer(state =>                {                    _publisher.Publish(                        _cupCollector.Get(),                        _ramCollector.Get(),                        _ioCollector.Get());                }, null, 0, _options.Interval);                return Task.CompletedTask;            }            //停止            public Task StopAsync(CancellationToken cancellationToken)            {                _timer?.Dispose();                return Task.CompletedTask;            }        }

把托管服务类加入到Hosting

  public static void Start()        {            var collector = new Collector();//方法实现            var host = new HostBuilder()//新建一个Hosting                //读取配置文件                .ConfigureAppConfiguration((context, builder) => builder.AddJsonFile("appsettings.json"))                .ConfigureServices((context, collection) => collection                    .AddSingleton<ICupCollector>(collector)//单例注入Cup                    .AddSingleton<IRAMCollector>(collector)//单例注入RAM                    .AddSingleton<IIOCollector>(collector)//单例注入IO                    .AddSingleton<AirEnvironmentPublisher>()//单例发布订阅                    .AddHostedService<AirEnvironmentService>()//把托管服务类加入到Hosting                    .AddOptions()                    .Configure<AirEnvironmentOptions>(                        context.Configuration.GetSection("AirEnvironment"))//把配置文件的时间间隔读取                )                //添加日志                .ConfigureLogging((context, builder) => builder                    .AddConfiguration(context.Configuration.GetSection("Logging"))                    .AddConsole())                .Build();            //运行            host.Run();        }

在配置文件中加入间隔时间和日志等级

.NET Core核心组件Hosting实践

按f5尝试一下,完美。如下图

.NET Core核心组件Hosting实践