Xharlie Xharlie - 3 months ago 30
C# Question

Performance Counter Instance Name vs. Process Name

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;
}


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

How are the instance name and process name related?

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;
}

Answer

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

Regular Processes

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!

Service Processes

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 Applications

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.

Conclusion

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.

(In the absence of further input, I will accept this as an answer. Feel free to correct me.)