65.9K
CodeProject 正在变化。 阅读更多。
Home

帮助创建 .NET Framework 中的 Provider 性能计数器 v 2.0

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2015年4月17日

CPOL

1分钟阅读

viewsIcon

18167

本技巧将帮助您在 .NET Framework 中创建 Provider 性能计数器 v 2.0。

引言

我想向您介绍一个 NuGet 包 DevUtils ETW IMBA,它将帮助您简单快速地创建支持 Windows Vista 中引入的新架构 (2.0) 的 性能计数器

背景

在 .NET Framework 4.5 中,添加了 System.Diagnostics.PerformanceData 空间中的类,这些类允许您在此新架构上创建计数器。但是要使用它们,您必须执行以下操作:

  1. 手动在 XML 清单中描述计数器,这些计数器在逻辑上分组为一组计数器。该计数器在组中由数值标识符定义,该标识符在计数器组内是唯一的。Provider 可以定义一个或多个计数器组。计数器组由 Provider 唯一的 GUID 标识。
  2. 记录清单后,您需要使用 CTRPP对其进行编译,这将创建一个 .rc 文件。接下来,创建一个编译后的资源文件 (.res),并将其添加到项目中。
  3. 使用 LodCtr将计数器注册到计算机中。

此包为您完成所有这些步骤。

Using

您只需要在代码中描述您的计数器:

    [CounterSource(Guid = "{ab8e1320-965a-4cf9-9c07-fe25378c2a23}")]
    sealed class MyCounterSource
    {
        #region MyLogicalDiskSet

        [CounterSet(CounterSetInstances.Multiple,
            Name = "My LogicalDisk",
            Description = "This is a sample counter set with multiple instances.")]
        public enum MyLogicalDiskSet
        {
            [Counter(CounterType.PerfCounterRawcount,
                DefaultScale = 1,
                Name = "My Free Megabytes",
                Description = "First sample counter.",
                DetailLevel = CounterDetailLevel.Standard)]
            MyFreeMegabytes = 1,

            [CounterAttributeReference]
            [CounterAttributeDisplayAsReal]
            [Counter(CounterType.PerfAverageTimer,
                DefaultScale = 1,
                BaseId = (int)MyAvgDiskTransfer,
                Name = "My Avg. Disk sec/Transfer",
                Description = "Second sample counter.",
                DetailLevel = CounterDetailLevel.Advanced)]
            MyAvgDiskSec,

            [CounterAttributeNoDisplay]
            [Counter(CounterType.PerfAverageBase,
                DetailLevel = CounterDetailLevel.Advanced)]
            MyAvgDiskTransfer,
        }

        #endregion

        #region MySystemObjectsSet

        [CounterSet(CounterSetInstances.Single,
            Name = "My System Objects",
            Description = "My System Objects Help.")]
        public enum MySystemObjectsSet
        {
            [CounterAttributeDisplayAsHex]
            [CounterAttributeNoDigitGrouping]
            [Counter(CounterType.PerfCounterRawcount,
                DefaultScale = 1,
                Name = "Process Count",
                Description = "Process Count Help.")]
            ProcessCount = 1,

            [Counter(CounterType.PerfCounterRawcount,
                Name = "Thread Count",
                Description = "Thread Count Help.")]
            ThreadCount,

            [Counter(CounterType.PerfElapsedTime,
                DefaultScale = 1,
                PerfTimeId = (int)SystemTime,
                PerfFreqId = (int)SystemFreq,
                Name = "System Elapsed Time",
                Description = "System Elapsed Time Help.",
                DetailLevel = CounterDetailLevel.Advanced)]
            SystemElapsedTime,

            [CounterAttributeNoDisplay]
            [Counter(CounterType.PerfCounterLargeRawcount)]
            SystemTime,

            [CounterAttributeNoDisplay]
            [Counter(CounterType.PerfCounterLargeRawcount)]
            SystemFreq
        }

        #endregion
   }

并在这些计数器中提供数据:

public static void Test()
{
    using (var diskSet = new CounterSet<MyLogicalDiskSet>())
    using (var objectsSet = new CounterSet<MySystemObjectsSet>())
    using (var diskSetInst = diskSet.CreateInstance("Default"))
    using (var objectsSetInst = objectsSet.CreateInstance("Default"))
    {
        var processCount = objectsSetInst[MySystemObjectsSet.ProcessCount];
        var myAvgDiskSec = diskSetInst[MyLogicalDiskSet.MyAvgDiskSec];
        var myAvgDiskTransfer = diskSetInst[MyLogicalDiskSet.MyAvgDiskTransfer];

        processCount.Value = 2;

        for (var i = 0; i < 10; ++i)
        {
            var beginTicks = Stopwatch.GetTimestamp();

            // takes some work
            Thread.Sleep(1000);

            var endTicks = Stopwatch.GetTimestamp();

            myAvgDiskSec.IncrementBy(endTicks - beginTicks);
            myAvgDiskTransfer.IncrementBy(1);
        }
    }
}

然后构建项目。

构建后,您将在 "bin\Debug\" 中获得两个文件:

  1. <项目名称>.IM.xml:这是清单本身,自动生成。
  2. <项目名称>.IM.dll:该文件仅包含资源。这些是计数器名称、集名称、行描述等。

此外,如果您拥有具有管理员权限的 VS,您的计数器将注册到系统中,您可以立即查看其结果。

注意:您可以通过将节插入项目文件中来禁用自动注册。

<PropertyGroup>
    <IMBASkipInstallManifest>true</IMBASkipInstallManifest>
</PropertyGroup> 

历史

  • 首次发布
© . All rights reserved.