在.NET中命名多实例性能计数器

时间:2010-06-07 15:28:11

标签: .net performancecounter

如果有多个具有相同名称的实例,Windows中的大多数实例性能计数器似乎自动(?)最后都有#n。

例如:如果您在Perfmon中查看Process类别,则会看到:

...
dwm
explorer
explorer#1
...

我有两个explorer.exe进程,因此第二个计数器的名称附加了#1。

当我尝试在.NET应用程序中执行此操作时:

  • 我可以创建类别,并注册实例(使用带PerformanceCounterCategory.Create的{​​{1}}。
  • 我可以打开计数器进行写入和写入。

当我第二次打开计数器时(在另一个过程中),它会打开相同的计数器。这意味着我有两个进程争夺计数器。

documentation for PerformanceCounter.InstanceName表示名称中不允许CounterCreationDataCollection

那么:我如何拥有实际上是多个实例的多实例性能计数器?第二个(和后续)实例的名称会附加#吗?

那就是:我知道我可以将进程ID(例如)放在实例名称上。这有效,但有一个不幸的副作用,即重新启动进程会产生新的PID,并且Perfmon继续监视旧计数器。

更新

我正在创建类别(和计数器),如下所示:

#n

我打开柜台如下:

const string categoryName = "Test App";
const string counterName = "Number of kittens";
string instanceName =
    Path.GetFileNameWithoutExtension(
        Process.GetCurrentProcess().MainModule.FileName);

if (!PerformanceCounterCategory.Exists(categoryName))
{
    var counterCreationDataCollection = new CounterCreationDataCollection
        {
            new CounterCreationData(counterName, "",
                PerformanceCounterType.NumberOfItems32)
        };

    PerformanceCounterCategory.Create(categoryName, "",
        PerformanceCounterCategoryType.MultiInstance,
        counterCreationDataCollection);
}

1 个答案:

答案 0 :(得分:2)

我认为你的问题在于.NET在性能计数器方面更加松散,实际上绕过了PerfLib Win API。

使用本机PerfLib API时,您可以在安装过程中注册类别 - 并使用句柄从进程创建实例。因此,使用本机API,没有直接的方式来共享计数器实例。因此,当使用相同的名称访问两个计数器实例时,它们实际上具有不同的句柄并且由#恰当标记。

在.NET中,您只需按名称寻址计数器和实例,您就有交叉更新的危险。当.NET取名并枚举(使用WMI)实例时,即使它们被不同的应用程序使用。

我认为添加PID *确实是最聪明的解决方案 - 因为你们都有更好的追踪能力而且没有碰撞。关于重启创建新计数器的问题,我没有看到问题;如果您允许在给定时间运行多个进程实例,您如何知道此实例是由于重新启动还是仅仅运行其他可执行文件而创建的?

如果在进程之间确实存在某种依赖关系,则可以清除过时的计数器或使用其他逻辑。在PerfMon中,您可以观看“*”所有实例。

*或者如果你在这个过程背后有一些逻辑,这个逻辑是在不考虑重启的情况下维护的 - 比如某种任务id。