例外:实例“实例名称”在指定的类别中不存在

时间:2011-04-29 13:30:50

标签: c# exception performancecounter

当我创建和使用这样的性能计数器时:

private readonly PerformanceCounter _cpuPerformanceCounter;
public ProcessViewModel(Process process)
        {

             _cpuPerformanceCounter = new PerformanceCounter("Process", "% Processor Time", process.ProcessName, true);
        }

public void Update()
        {
            CPU = (int)_cpuPerformanceCounter.NextValue() / Environment.ProcessorCount; // Exception
        }

...我收到异常实例'实例名称'在指定的类别中不存在,并且不明白原因。

P.S。代码

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <settings>
      <performanceCounters enabled="true"/>
    </settings>
  </system.net>
</configuration>

...包含在App.config中。

5 个答案:

答案 0 :(得分:1)

我认为当有多个具有相同名称的进程时,您的问题就会发生。 PerfMon所做的是将#1,#2等附加到进程名称。这意味着当您尝试读取“MyApp”的性能监视器时,执行两次MyApp.exe将导致此异常。以下是解决此问题的一种方法的链接:Read performance counters by pid

答案 1 :(得分:1)

添加到以前的帖子,我看到进程的格式类似于&lt; ProcessName&gt; _&lt; ProcessId&gt; - 取决于您运行应用程序的操作系统(Win XP,Win Vista,Win 7,Win 2003或2008 Server)。为了有一种可靠的方法来识别您的进程名称以便在未来获得其他性能计数器,函数可能如下所示:

    private string ObtainProcessName()
    {
        string baseProcessName;
        string processName = null;
        int processId;
        bool notFound = true;
        int processOptionsChecked = 0;
        int maxNrOfParallelProcesses = 3 + 1;

        try
        {
            baseProcessName = Process.GetCurrentProcess().ProcessName;
        }
        catch (Exception exception)
        {
            return null;
        }

        try
        {
            processId = Process.GetCurrentProcess().Id;
        }
        catch (Exception exception)
        {
            return null;
        }

        while (notFound)
        {
            processName = baseProcessName;
            if (processOptionsChecked > maxNrOfParallelProcesses)
            {
                break;
            }

            if (1 == processOptionsChecked)
            {
                processName = string.Format("{0}_{1}", baseProcessName, processId);
            }
            else if (processOptionsChecked > 1)
            {
                processName = string.Format("{0}#{1}", baseProcessName, processOptionsChecked - 1);
            }

            try
            {
                PerformanceCounter counter = new PerformanceCounter("Process", "ID Process", processName);
                if (processId == (int)counter.NextValue())
                {
                    notFound = !true;
                }
            }
            catch (Exception)
            {
            }
            processOptionsChecked++;
        }
        return processName;
    }

答案 2 :(得分:1)

以下是我对所有流程和多个流程实例的解决方案:

MyComponent.propTypes = {
  foo: PropTypes.string,
};

答案 3 :(得分:0)

使用pid后缀(注册表ProcessNameFormat = 1)的origninal格式似乎已从.NET 4.5(msdn link)更改为“processame_pid_rid”。因此,目前所写的已接受的答案可能不再适用于该案例。

此解决方案仍适用于较新的格式:

https://weblog.west-wind.com/posts/2014/Sep/27/Capturing-Performance-Counter-Data-for-a-Process-by-Process-Id

但是,所有这些匹配的解决方案都可能容易出现竞争情况,即实例名称在确定实例名称之后但在分配新的PerformanceCounter()之前由于进程退出而变化(#9变为#8)。 / p>

MS提供一个直接接受Pid(可能现在是RuntimeId?)的PerformanceCounter构造函数会更有意义,因为实例名称可以随时更改。

答案 4 :(得分:-1)

您可以查看此代码

Use > new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
Instead of> new PerformanceCounter("Processor", "% Processor Time", "_Total");