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
相关产品推荐
相关产品推荐

