You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PerformanceCounter偶发‘指定类别计数器布局无效’异常排查求助

Windows服务中PerformanceCounter偶发异常问题处理

我们在Windows服务中每5分钟监控若干个PerformanceCounter,代码会偶发抛出异常,异常触发时机不确定,有时稳定运行数日才出现,重启服务或等待一段时间后可自行恢复。怀疑和PerformanceCounter释放不当有关,可能GC清理后恢复正常。

异常信息如下:

错误信息:指定类别的计数器布局无效,AverageCount64、AverageTimer32等类型的计数器必须紧跟AverageBase等基础计数器类型。

该问题与Stack Overflow上的同类问题高度相似。

相关代码

读取性能计数器的方法

private static float ReadPerformanceCounter(string CategoryName, string CounterName, string InstanceName)
{
    using (PerformanceCounter performanceCounter = new PerformanceCounter())
    {
        performanceCounter.CategoryName = CategoryName;
        performanceCounter.CounterName = CounterName;
        performanceCounter.InstanceName = InstanceName;

        // 首次读取值始终为0
        var firstValue = performanceCounter.NextValue();

        System.Threading.Thread.Sleep(1000);

        // 该值与任务管理器读数一致
        var secondValue = performanceCounter.NextValue();
        
        return secondValue;
    }
}

调用示例

float processor = ReadPerformanceCounter("Processor", "% Processor Time", "_Total");
float disk = ReadPerformanceCounter("PhysicalDisk", "% Disk Time", "_Total");
float memory = ReadPerformanceCounter("Memory", "Page Reads/sec", null);
float networkClient = ReadPerformanceCounter("SMB Client Shares", "Avg. Data Queue Length", "_Total");

问题原因与解决建议

  • 避免频繁创建销毁实例:当前每次读取都新建PerformanceCounter实例并释放,系统级资源的频繁操作可能导致计数器元数据加载异常。建议将常用计数器实例缓存为静态对象,服务启动时初始化,后续复用。
  • 成对读取依赖计数器:像"Avg. Data Queue Length"这类Average类型的计数器,必须和对应的Base计数器(如"Avg. Data Queue Length Base")配合读取,系统需要两个值计算最终结果,单独读取非Base计数器可能引发状态异常。
  • 确保资源及时回收:虽然using会调用Dispose,但PerformanceCounter的非托管资源释放可能存在延迟。必要时可在Dispose后手动触发GC回收,确保资源及时清理。
  • 优化线程处理逻辑:方法内的Thread.Sleep(1000)会阻塞调用线程,连续读取多个计数器会导致服务响应延迟。建议改用异步等待或单独线程池线程执行读取操作。

内容的提问来源于stack exchange,提问作者roberth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 09:37:15