Получить имя экземпляра счетчика производительности (w3wp # XX) из идентификатора рабочего процесса ASP.NET - PullRequest
13 голосов
/ 22 сентября 2008

Я хотел бы отобразить статистику памяти (рабочий набор, GC и т. Д.) На веб-странице, используя счетчики производительности .NET / Process. К сожалению, если на этом сервере есть несколько пулов приложений, они различаются по индексу (# 1, # 2 и т. Д.), Но я не знаю, как сопоставить идентификатор процесса (который у меня есть) с этим индексом #xx. Есть ли программный способ (с веб-страницы ASP.NET)?

Ответы [ 5 ]

11 голосов
/ 29 января 2009
private static string GetProcessInstanceName(int pid)
{
  PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");

  string[] instances = cat.GetInstanceNames();
  foreach (string instance in instances)
  {

     using (PerformanceCounter cnt = new PerformanceCounter("Process",  
          "ID Process", instance, true))
     {
        int val = (int) cnt.RawValue;
        if (val == pid)
        {
           return instance;
        }
     }
  }
  throw new Exception("Could not find performance counter " + 
      "instance name for current process. This is truly strange ...");
}
11 голосов
/ 22 сентября 2008

Первый хит в Google:

Появляются несколько счетчиков производительности CLR, имена которых напоминают "W3wp # 1"

Когда несколько рабочих процессов ASP.NET работают, Common Language Runtime (CLR) счетчики производительности будут иметь имена, которые напоминают "W3wp # 1" или "W3sp # 2" и так далее. Это было исправлено в .NET Framework 2.0, чтобы включить счетчик с именем ID процесса в .NET Объект производительности памяти CLR. это Счетчик отображает идентификатор процесса для пример. Вы можете использовать этот счетчик для определить счетчик производительности CLR это связано с процессом.

Также KB 281884 :

По умолчанию монитор производительности (Perfmon.msc) отображает несколько процессы, которые имеют одинаковое имя перечисляя процессы в следующим образом:

Процесс № 1 Процесс № 2 Процесс № 3

Performance Monitor также может отображать эти процессы путем добавления идентификатор процесса (PID) к имени в следующим образом:

Process_PID

1 голос
/ 23 октября 2009

Несмотря на то, что изменение настроек реестра выглядит довольно просто, к сожалению, большинство из нас не имеют права делать это на сервере (или мы не хотим трогать это!). В этом случае есть небольшой обходной путь. Я писал об этом здесь .

1 голос
/ 22 мая 2009

Пример chiru не работает в конкретном случае - когда у вас есть две версии одной и той же программы, названные одинаково, и одна не является .net, и вы запускаете версию .net после версии, отличной от .NET. Версия .Net будет называться applicationaion # 1, но когда вы обращаетесь к счетчикам производительности CLR, используя это имя, имена экземпляров на счетчике имеют имя без # 1, поэтому вы получаете ошибки.

Ник.

0 голосов
/ 14 ноября 2016

Я знаю, что на него уже отвечали, но только ради полного рабочего кода я выкладываю это решение. Обратите внимание, этот код основан на методе, представленном M4N в этой цепочке:

public static long GetProcessPrivateWorkingSet64Size(int process_id)
{
  long process_size = 0;
  Process process = Process.GetProcessById(process_id);
  if (process == null) return process_size;
  string instanceName = GetProcessInstanceName(process.Id);
  var counter = new PerformanceCounter("Process", "Working Set - Private", instanceName, true);
  process_size = Convert.ToInt32(counter.NextValue()) / 1024;
  return process_size;
}

public static string GetProcessInstanceName(int process_id)
{
  PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");
  string[] instances = cat.GetInstanceNames();
  foreach (string instance in instances)
  {
    using (PerformanceCounter cnt = new PerformanceCounter("Process", "ID Process", instance, true))
    {
       int val = (int)cnt.RawValue;
       if (val == process_id)
         return instance;
    }
  }
  throw new Exception("Could not find performance counter ");
}

Кроме того, если вы хотите получить общую память нескольких экземпляров одного и того же процесса, используйте описанные выше методы со следующим:

public static long GetPrivateWorkingSetForAllProcesses(string ProcessName)
{
  long totalMem = 0;
  Process[] process = Process.GetProcessesByName(ProcessName);
  foreach (Process proc in process)
  {
    long memsize = GetProcessPrivateWorkingSet64Size(proc.Id);
    totalMem += memsize;
  }
  return totalMem;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...