写在前面
在 Microsoft.Extensions.Diagnostics.ResourceMonitoring 包提供了一系列定制 API,专用于监视 .NET 应用程序的资源利用率。
为了让控制台输出的样式更美观,可以安装一下Spectre.Console这个包
本例主要通过 IResourceMonitor 来获取资源状态信息,该接口支持检索与 CPU 和内存使用情况相关的数据,并且当前与 Windows 和 Linux 平台兼容。
示例代码中用到的 Microsoft.Extensions.Logging 类库也需要通过NuGet安装一下。
代码实现
cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.ResourceMonitoring;
using Microsoft.Extensions.Logging;
using Spectre.Console;
public class Program
{
public static void Main(string[] args)
{
var services = new ServiceCollection()
.AddLogging()
.AddResourceMonitoring();
var provider = services.BuildServiceProvider();
var monitor = provider.GetRequiredService<IResourceMonitor>();
_ = StartMonitoringAsync(monitor, new CancellationToken());
Console.ReadKey();
}
static async Task StartMonitoringAsync(IResourceMonitor monitor, CancellationToken cancellationToken)
{
var table = new Table()
.Centered()
.Title("Resource Monitoring", new Style(foreground: Color.Purple, decoration: Decoration.Bold))
.Caption("Updates every three seconds. *GTD: Guaranteed ", new Style(decoration: Decoration.Dim))
.RoundedBorder()
.BorderColor(Color.Cyan1)
.AddColumns(
[
new TableColumn("Time").Centered(),
new TableColumn("CPU %").Centered(),
new TableColumn("Memory %").Centered(),
new TableColumn("Memory (bytes)").Centered(),
new TableColumn("GTD / Max Memory (bytes)").Centered(),
new TableColumn("GTD / Max CPU (units)").Centered(),
]);
await AnsiConsole.Live(table)
.StartAsync(async ctx =>
{
var window = TimeSpan.FromSeconds(3);
while (cancellationToken.IsCancellationRequested is false)
{
var utilization = monitor.GetUtilization(window);
var resources = utilization.SystemResources;
table.AddRow(
[
$"{DateTime.Now:T}",
$"{utilization.CpuUsedPercentage:p}",
$"{utilization.MemoryUsedPercentage:p}",
$"{utilization.MemoryUsedInBytes:#,#}",
$"{resources.GuaranteedMemoryInBytes:#,#} / {resources.MaximumMemoryInBytes:#,#}",
$"{resources.GuaranteedCpuUnits} / {resources.MaximumCpuUnits}",
]);
ctx.Refresh();
await Task.Delay(window);
}
});
Console.CancelKeyPress += (_, e) =>
{
e.Cancel = true;
};
}
}