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();
}
在配置文件中加入间隔时间和日志等级
按f5尝试一下,完美。如下图