2011-04-29 120 views
9

当我创建和使用性能计数器是这样的:例外:实例“实例名称”不指定类别中存在

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中。

+1

这似乎为我工作。我为ProcessName参数尝试了'Process.GetCurrentProcess()。ProcessName'。 – 2011-04-29 13:57:35

+0

它是位于ProcessViewModel类中的代码。我使用它来迭代Process.GetProcesses()并获取有关系统中进程的信息。 – 2011-04-29 14:16:37

+0

它似乎也适用于我! – 2011-05-28 20:16:13

回答

1

添加到先前的文章,我已经看到了正在格式化的过程就像<ProcessName> _ <的ProcessID > - 这取决于你在(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; 
    } 
+7

哎哟,我希望你不要把这样的事情在生产代码:'NOTFOUND = TRUE;' – ChrisWue 2013-07-01 21:43:52

+1

可以(https://support.microsoft.com/en-us/help/ [通过注册表配置]! 281884 /所述工艺对象合性能监视器可以显示过程的IDS-PID的)的实例名是否使用#1,#2等或PID。 – 2017-07-19 12:26:47

1

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

-1

您可以检查此代码

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

为什么,它有什么作用? – markus 2012-12-11 23:08:48

0

的origninal格式使用pid后缀(注册表ProcessNameFormat = 1)似乎已从.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

但是,所有这些匹配的解决方案可能会有竞争状态,其中实例名称的变化,由于进程退出(#9成为# 8)刚确定实例名称之后,但在新的PerformanceCounter()被分配之前。

它将使更多的意义为MS提供接受一个PID一个的PerformanceCounter构造函数(也可能是现在RuntimeId?)直接从实例名称可以动态改变。

0

这里是我的所有流程和多个流程实例的解决方案:

var processes = Process.GetProcesses().GroupBy(g => g.ProcessName); 
     List<Tuple<string, PerformanceCounter>> pcList = new List<Tuple<string, PerformanceCounter>>(); 
     foreach (var pg in processes) 
     { 
      if (pg.First().ProcessName == "Idle") 
       continue; 

      if (pg.Count() == 1) 
      { 
       var process_cpu = new PerformanceCounter(
          "Process", 
          "% Processor Time", 
          pg.First().ProcessName 
           ); 
       process_cpu.NextValue(); 
       pcList.Add(new Tuple<string, PerformanceCounter>(pg.First().ProcessName, process_cpu)); 
      } 
      else 
      { 
       int id = 1; 
       foreach(var p in pg) 
       { 
        var process_cpu = new PerformanceCounter(
          "Process", 
          "% Processor Time", 
          p.ProcessName + "#" + id 
           ); 
        process_cpu.NextValue(); 
        pcList.Add(new Tuple<string, PerformanceCounter>(p.ProcessName + "#" + id, process_cpu)); 
        id++; 
       } 
      } 
     }