ASP.NET Framework 4.8中使用.NET Core官方EventCounter示例代码报错问题咨询
Why does the official .NET Core EventCounter sample fail in ASP.NET Framework 4.8?
你碰到的问题完全是因为**.NET Framework 4.8和.NET Core/.NET 5+之间的EventCounter API差异**导致的——微软官方文档里的示例是针对.NET Core生态编写的,和.NET Framework的实现有明显区别。
1. 具体的API差异点
你已经自己排查到了关键:.NET Framework 4.8中的EventCounter只保留了最基础的功能,没有实现.NET Core里的新增特性:
DisplayName/DisplayUnits属性:这两个是.NET Core 2.2及以后版本才添加的,用来给计数器设置友好名称和单位,方便监控工具(比如dotnet-counters)识别展示。.NET Framework的EventCounter完全没有这两个属性。Dispose()方法:.NET Core版本的EventCounter实现了IDisposable接口,支持手动释放资源;但.NET Framework里的EventCounter根本没实现这个接口,所以调用Dispose()会直接报错。
2. 为什么会有这种差异?
EventCounter最初是为.NET Core设计的轻量性能监控组件,后来虽然被移植到了.NET Framework,但只做了最基础的功能适配——毕竟.NET Framework是成熟的旧框架,微软不会再给它添加太多新API,只会做必要的维护性更新。
3. 针对ASP.NET Framework 4.8的替代方案
方案一:简化使用EventCounter
去掉.NET Framework不支持的属性和方法,只保留基础的性能统计功能:
using System.Diagnostics.Tracing; [EventSource(Name = "Sample.EventCounter.Minimal")] public sealed class MinimalEventCounterSource : EventSource { public static readonly MinimalEventCounterSource Log = new MinimalEventCounterSource(); private EventCounter _requestCounter; private MinimalEventCounterSource() { // 只保留基础构造调用,无法设置DisplayName和DisplayUnits _requestCounter = new EventCounter("request-time", this); } public void Request(string url, long elapsedMilliseconds) { WriteEvent(1, url, elapsedMilliseconds); // 注意:.NET Framework的WriteMetric只接受float参数,需要转换 _requestCounter?.WriteMetric((float)elapsedMilliseconds); } protected override void Dispose(bool disposing) { // .NET Framework的EventCounter不需要手动Dispose,直接调用基类方法即可 base.Dispose(disposing); } }
这样代码就能正常编译运行,只是监控工具里看到的计数器会是原始的request-time,没有友好名称和单位标注。
方案二:使用.NET Framework原生性能计数器
如果需要更完善的性能监控(包括友好名称、单位、可视化展示),推荐用.NET Framework自带的PerformanceCounter——这是Windows平台原生的成熟性能监控组件,示例代码如下:
using System.Diagnostics; public class RequestPerformanceTracker { private readonly PerformanceCounter _requestTimer; private readonly PerformanceCounter _requestTimerBase; public RequestPerformanceTracker() { // 先检查计数器分类是否存在,不存在则创建 if (!PerformanceCounterCategory.Exists("WebForms Request Counters")) { var counterData = new CounterCreationDataCollection(); // 添加平均请求时间计数器 counterData.Add(new CounterCreationData( "Avg Request Processing Time", "Average time taken to process web requests", PerformanceCounterType.AverageTimer32)); // 对应的基础计数器(必须成对存在) counterData.Add(new CounterCreationData( "Avg Request Time Base", "Base counter for average request time calculation", PerformanceCounterType.AverageBase)); PerformanceCounterCategory.Create( "WebForms Request Counters", "Performance counters for ASP.NET WebForms requests", PerformanceCounterCategoryType.SingleInstance, counterData); } // 初始化计数器实例 _requestTimer = new PerformanceCounter( "WebForms Request Counters", "Avg Request Processing Time", false); _requestTimerBase = new PerformanceCounter( "WebForms Request Counters", "Avg Request Time Base", false); } public void RecordRequest(long elapsedMilliseconds) { // 转换为PerformanceCounter需要的计时器ticks单位 _requestTimer.IncrementBy(elapsedMilliseconds * 10000); _requestTimerBase.Increment(); } }
这个方案可以直接在Windows性能监视器(PerfMon)里查看统计数据,功能更完整,适配.NET Framework环境。
内容的提问来源于stack exchange,提问作者Diogo
相关产品推荐
相关产品推荐

