c# - 性能计数器实例名称与进程名称

标签 c# process performancecounter

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

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 的值匹配。

实例名和进程名有什么关系?

我问是因为我想简化例程中的 foreach 循环,这样我就不必为无法匹配当前进程的实例获取 ID Process 计数器.我设想的 final方法可能如下所示:

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

最佳答案

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

常规流程

看起来,对于具有给定名称的第一个常规进程,进程名称与实例名称相匹配。对于同名的后续进程,通过附加#1#2、...

修改实例名称

令人担忧的是,与进程关联的实例名称 似乎也可能发生变化。这似乎发生在数字序列中较早的过程结束时。在确定实例名称和获取相关计数器之间存在竞争条件!

服务流程

在服务控制管理器下运行的 Windows NT 服务的行为方式与常规进程的行为方式相同。如果您在数字序列中较早地结束服务进程,实例名称也会发生变化。

ASP.NET 应用程序

除了进程名称是 w3wp 之外,同样的假设适用于在 IIS 下托管的应用程序。不同的应用程序。池肯定有不同的进程,并且通过启动和停止应用程序。池,我确定实例名称在与上述相同的情况下以相同的方式更改。

结论

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

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

此外,当使用返回的实例名称时,确认上述竞争条件的存在是非常重要的。

(在没有进一步输入的情况下,我会接受这个作为答案。请随时纠正我。)

关于c# - 性能计数器实例名称与进程名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29922791/

相关文章:

c++ - 多进程同步的输出流锁定?

c# - 在 C# 中异步检索 Cpu 使用情况

c++ - 如何确定 PdhExpandWildCardPath 结果中的主要网络适配器?

c# - 单击按钮时如何检查已经打开的窗口?

c# - 快速增加内存使用率C#

c# - 在 C# 中将字符串转换为标志枚举

c# - 该文件使用什么编码?

c - 操作系统、C 和进程内存分配

c# - 在运行时唯一标识对象的选项?

c# - C# 中的 var 与 Object