.NET 本身没有内置一个叫做 viewstatus 的命令或工具,这个术语通常来源于 Linux/Unix 系统的 view 命令(如 view filename,实际是 vim filename 的别名)和 status 概念的结合,泛指“查看某个对象或服务的当前状态”。

.net viewstatus教程
(图片来源网络,侵删)

.NET 开发中,“查看状态”是一个非常核心的需求,但其实现方式取决于你要查看的“对象”是什么,是:

  • 一个 Web 应用的健康状态
  • 一个 后台服务的运行状态
  • 一个 数据库连接的状态
  • 一个 长时间运行任务的进度
  • 还是整个 .NET 应用的内部状态(如内存、CPU)?

针对这些不同的场景,.NET 提供了多种现代化的解决方案,下面我将分门别类地为你提供详细的教程和代码示例。


检查 Web API 或微服务的健康状态

这是最常见的需求之一,通常被称为 健康检查,你希望监控系统或负载均衡器能够快速知道你的应用是否“活着”并且能正常响应。

核心技术:Microsoft.Extensions.Diagnostics.HealthChecks

这是 ASP.NET Core 官方推荐的健康检查库。

.net viewstatus教程
(图片来源网络,侵删)

教程步骤:

创建一个 ASP.NET Core Web API 项目

如果你还没有项目,可以通过命令行创建:

dotnet new webapi -n HealthCheckDemo
cd HealthCheckDemo

安装必要的 NuGet 包

默认情况下,健康检查功能已经包含在 Microsoft.AspNetCore.App 元包中,但如果你需要检查特定资源(如数据库、Redis),需要额外安装。

.net viewstatus教程
(图片来源网络,侵删)
# 检查 SQL Server 数据库状态(示例)
dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks.SqlServer

配置健康检查服务

Program.cs 文件中(对于 .NET 6+ 的 Minimal API 风格)或 Startup.csConfigureServices 方法中配置。

// Program.cs (.NET 6+)
var builder = WebApplication.CreateBuilder(args);
// 1. 添加健康检查服务
builder.Services.AddHealthChecks()
    // 2. 添加一个检查项,命名为 "self",检查应用自身是否可以响应
    .AddCheck("self", () => HealthCheckResult.Healthy("OK"))
    // 3. 添加一个数据库检查项(需要连接字符串)
    // 假设在 appsettings.json 中配置了 "DefaultConnection"
    .AddSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection"),
        name: "sqlserver",
        tags: new[] { "database", "sql" }); // 可以给检查项打上标签
var app = builder.Build();
// 4. 创建一个健康检查端点
app.MapHealthChecks("/healthz"); // 访问 http://localhost:5000/healthz
// ... 其他配置
app.MapGet("/", () => "Welcome to run the /healthz endpoint!");
app.Run();

运行并测试

  • 运行你的应用:dotnet run
  • 在浏览器或 Postman 中访问 http://localhost:5000/healthz (端口可能不同)。

可能的结果:

  • 健康状态 (Healthy):

    {
      "status": "Healthy",
      "totalDuration": "00:00:00.0012345",
      "entries": {
        "self": {
          "status": "Healthy",
          "duration": "00:00:00.0001234",
          "data": {
            "description": "OK"
          }
        },
        "sqlserver": {
          "status": "Healthy",
          "duration": "00:00:00.4567890",
          "data": {},
          "tags": ["database", "sql"]
        }
      }
    }
  • 不健康状态 (Degraded/Unhealthy): 如果数据库连接失败,sqlserver 检查项会返回 Unhealthy,整个状态也会变为 Unhealthy


查看后台服务或长时间运行任务的状态

当你有一个 BackgroundService 或一个长时间运行的任务时,你可能想知道它的进度、是否卡住或已完成。

核心技术:IHostedService + CancellationToken + 状态报告模式

教程步骤:

创建一个继承自 BackgroundService 的服务

// Services/LongRunningTaskService.cs
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;
public class LongRunningTaskService : BackgroundService
{
    private readonly ILogger<LongRunningTaskService> _logger;
    private int _progress = 0; // 简单的状态表示
    public LongRunningTaskService(ILogger<LongRunningTaskService> logger)
    {
        _logger = logger;
    }
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Long-running task is starting.");
        for (int i = 0; i <= 100; i += 10)
        {
            // 检查是否请求取消
            stoppingToken.ThrowIfCancellationRequested();
            _progress = i;
            _logger.LogInformation($"Task progress: {_progress}%");
            await Task.Delay(1000, stoppingToken); // 模拟工作
        }
        _logger.LogInformation("Long-running task has completed.");
    }
    // 提供一个公共方法来获取当前状态
    public int GetProgress()
    {
        return _progress;
    }
}

Program.cs 中注册该服务

// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHostedService<LongRunningTaskService>();
// ... 其他配置
var app = builder.Build();
// 添加一个端点来查看任务状态
app.MapGet("/taskstatus", (LongRunningTaskService taskService) =>
{
    var progress = taskService.GetProgress();
    return Results.Ok(new { Status = progress == 100 ? "Completed" : "Running", Progress = progress });
});
app.Run();

运行并测试

  • 运行应用:dotnet run
  • 访问 http://localhost:5000/taskstatus,你会看到进度从 0% 逐步增加到 100%。

进阶:使用更复杂的状态对象 当状态很复杂时,可以创建一个 Status 类,并通过 IQueryablegRPC 暴露它,甚至使用 SignalR 实现实时状态推送。


检查 .NET 应用的内部运行时状态

有时你想知道应用本身消耗了多少内存、CPU 等。

核心技术:System.DiagnosticsMicrosoft.Extensions.Diagnostics.Metrics

教程步骤(使用 .NET 6+ 的内置支持):

启用指标收集

Program.cs 中,.NETMinimal API 已经内置了对 OpenTelemetry 规范的指标支持,默认是启用的。

// Program.cs
var builder = WebApplication.CreateBuilder(args);
// 默认情况下,Metrics 已经被收集,你可以添加一个 exporter 将其导出。
// 导出到 Prometheus:
// builder.Services.AddMetrics();
var app = builder.Build();
// 暴露一个 /metrics 端点,Prometheus 可以抓取这里的数据
// 如果你使用的是最新的 .NET 8,这个功能可能已内置或需要简单配置
// 对于 .NET 6/7,你可能需要使用 `prometheus-net` 库
app.MapMetrics(); // 如果你的 .NET 版本支持
app.MapGet("/", () => "Welcome to check the /metrics endpoint!");
app.Run();

如何查看这些指标?

直接访问 /metrics 端点得到的是 Prometheus 格式的原始数据,不易读,通常的做法是:

  • 使用 Prometheus + Grafana:

    1. 在服务器上部署 Prometheus。
    2. 配置 Prometheus 去抓取你的应用 /metrics 端点。
    3. 部署 Grafana,并连接 Prometheus 作为数据源。
    4. 在 Grafana 中创建仪表盘,可视化内存、CPU、请求数等指标。
  • 使用 Application Insights:

    1. Program.cs 中配置 Application Insights
    2. 它会自动收集大量的遥测数据,包括性能计数器,并在 Azure 门户中提供漂亮的图表和监控视图。

手动获取内存使用情况(代码示例)

如果你想在自己的代码中获取内存信息:

app.MapGet("/memory-status", () =>
{
    var currentMemory = GC.GetTotalMemory(false) / 1024.0 / 1024.0; // MB
    var workingSet = Environment.WorkingSet / 1024.0 / 1024.0; // MB
    return Results.Ok(new
    {
        CurrentMemoryMB = $"{currentMemory:F2}",
        WorkingSetMB = $"{workingSet:F2}"
    });
});

检查数据库连接状态

这是一个更具体的健康检查,场景一中的 AddSqlServer 就是一个例子,这里我们展示一个更通用的 ADO.NET 方式。

栞心技术:AddCheck + 自定义健康检查逻辑

创建自定义健康检查类

// Services/CustomDatabaseHealthCheck.cs
using Microsoft.Extensions.Diagnostics.HealthChecks;
using System.Data.Common;
using System.Threading;
using System.Threading.Tasks;
public class CustomDatabaseHealthCheck : IHealthCheck
{
    private readonly DbConnection _connection;
    public CustomDatabaseHealthCheck(DbConnection connection)
    {
        _connection = connection;
    }
    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        try
        {
            // 如果连接未打开,则尝试打开
            if (_connection.State == System.Data.ConnectionState.Closed)
            {
                await _connection.OpenAsync(cancellationToken);
            }
            // 执行一个简单的查询来验证连接
            using var command = _connection.CreateCommand();
            command.CommandText = "SELECT 1"; // 最简单的查询
            await command.ExecuteScalarAsync(cancellationToken);
            return HealthCheckResult.Healthy("Database connection is healthy.");
        }
        catch (Exception ex)
        {
            // 连接失败,返回不健康状态
            return new HealthCheckResult(
                context.Registration.FailureStatus,
                "Database connection is unhealthy.",
                ex: ex);
        }
    }
}

Program.cs 中注册

// Program.cs
var builder = WebApplication.CreateBuilder(args);
// 获取数据库连接字符串
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
// 创建一个 DbConnection 对象(以 SqlClient 为例)
using var connection = new System.Data.SqlClient.SqlConnection(connectionString);
builder.Services
    .AddHealthChecks()
    .AddCheck<CustomDatabaseHealthCheck>(
        "custom_database_check", // 名称
        tags: new[] { "database" }); // 标签
// ... 其他配置
var app = builder.Build();
app.MapHealthChecks("/health");
app.Run();

总结与对比

场景 核心技术 优点 适用场景
Web API 健康状态 Microsoft.Extensions.Diagnostics.HealthChecks 官方支持,标准化,易于集成监控系统(如 K8s, LB) 微服务、云原生应用、需要负载均衡器探针
后台任务状态 IHostedService + 自定义 API 灵活,可自定义状态模型,与业务逻辑紧密结合 长时间运行的数据处理、定时任务、需要用户查看进度的场景
应用内部状态 Metrics (OpenTelemetry) + Prometheus/Grafana 专业级监控,可视化能力强,历史数据分析 生产环境性能监控、容量规划、故障排查
特定资源状态 自定义 IHealthCheck 可针对任何自定义逻辑(如检查文件系统、调用外部 API) 需要监控非标准资源的复杂应用

希望这份详细的教程能帮助你理解在 .NET 中如何实现各种“查看状态”的功能!你可以根据你的具体需求选择最适合的方案。