性能计数器实例名称与进程名称 [英] Performance Counter Instance Name vs. Process Name

查看:157
本文介绍了性能计数器实例名称与进程名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在连接到Process类别中的各种性能计数器.我正在使用以下c#方法来确定获取计数器时要使用的实例名称:

I am connecting to various performance counters in the Process category. I am using the following c# method to determine the instance name to use when acquiring the counters:

private const string _categoryName = "Process";
private const string _processIdCounter = "ID Process";

public static bool TryGetInstanceName(Process process, out string instanceName)
{
    PerformanceCounterCategory processCategory = new PerformanceCounterCategory(_categoryName);
    string[] instanceNames = processCategory.GetInstanceNames();
    foreach (string name in instanceNames)
    {
        using (PerformanceCounter processIdCounter = new PerformanceCounter(_categoryName, _processIdCounter, name, true))
        {
            if (process.Id == (int)processIdCounter.RawValue)
            {
                instanceName = name;
                return true;
            }
        }
    }

    instanceName = null;
    return false;
}

现在,我注意到返回的实例名称通常与Process.ProcessName的值匹配.

Now, I have noticed that the instance name returned usually matches the value of Process.ProcessName.

实例名称和进程名称如何关联?

我问是因为我想简化例程中的foreach循环,这样我就不必为与当前进程不匹配的实例获取ID Process计数器.我设想了一个最终的方法,可能看起来像这样:

I ask because I want to simplify the foreach loop in the routine so that I do not have to acquire the ID Process counter for instances that cannot match the current process. I envision a final method that might look like this:

public static bool TryGetInstanceName(Process process, out string instanceName)
{
    PerformanceCounterCategory processCategory = new PerformanceCounterCategory(_categoryName);
    string[] instanceNames = processCategory.GetInstanceNames();
    foreach (string name in instanceNames)
    {
        if (name /* more or less matches */ process.ProcessName)
        {
            using (PerformanceCounter processIdCounter = new PerformanceCounter(_categoryName, _processIdCounter, name, true))
            {
                // ...
            }
        }
    }

    instanceName = null;
    return false;
}

推荐答案

看到没有答案,我进行了更多的试验和错误测试,并观察到以下行为:

Seeing that an answer was not forthcoming, I did some more trial and error testing and observed the following behaviour:

常规流程

对于具有给定名称的第一个常规进程,该进程名称似乎与实例名称匹配.对于具有相同名称的后续进程,通过添加#1#2,...

It appears that, for the first regular process with a given name, the process name matches the instance name. For subsequent processes with the same name, the instance name is modified by appending #1, #2, ...

令人震惊的是,与流程关联的实例名称也似乎有可能发生变化.当数字序列中较早的过程结束时,似乎会发生这种情况.在确定实例名称和获取相关计数器之间存在竞争条件!

Alarmingly, it also appears to be possible for the instance name associated with the process to change. This appears to happen when processes earlier in the numeric sequence end. There is a race-condition between determining the instance name and acquiring the relevant counters!

服务流程

在服务控制管理器下运行的Windows NT服务的行为似乎与常规进程的行为相同.如果您按数字顺序更早结束服务进程,则实例名称也似乎会更改.

Windows NT Services running under the Service Control Manager appear to behave in the same way that regular processes behave. The instance name also appears to change if you end a service-process earlier in the numeric sequence.

ASP.NET应用程序

相同的假设适用于IIS下托管的应用程序,但进程名称为w3wp.不同的应用程序.池肯定会通过启动和停止应用程序来获得不同的过程.池中,我确定在与上述相同的情况下,实例名称的更改方式相同.

The same assumptions work for applications hosted under IIS except that the process name is w3wp. Different app. pools definitely get different processes and, by starting and stopping app. pools, I ascertained that the instance name changes in the same way, under the same circumstances as above.

结论

我的结论是,实例名称总是开头,进程名称和方法可以如下修改:

My conclusion is that the instance name always starts with the process name and the method can be modified as follows:

public static bool TryGetInstanceName(Process process, out string instanceName)
{
    PerformanceCounterCategory processCategory = new PerformanceCounterCategory(_categoryName);
    string[] instanceNames = processCategory.GetInstanceNames();
    foreach (string name in instanceNames)
    {
        if (name.StartsWith(process.ProcessName))
        {
            using (PerformanceCounter processIdCounter = new PerformanceCounter(_categoryName, _processIdCounter, name, true))
            {
                if (process.Id == (int)processIdCounter.RawValue)
                {
                    instanceName = name;
                    return true;
                }
            }
        }
    }

    instanceName = null;
    return false;
}

此外,至关重要的是,当使用返回的实例名称时,必须承认上述竞争条件的存在.

Additionally, it is vitally important that one acknowledges the presence of the race-condition mentioned above when using the instance name returned.

(在没有进一步输入的情况下,我将接受此作为答案.请随时纠正我.)

这篇关于性能计数器实例名称与进程名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆