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

StackOverflow https://stackoverflow.com/questions/113930

Вопрос

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

Это было полезно?

Решение

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

Появится несколько счетчиков производительности CLR с именами, похожими на «W3wp#1».

Когда работают несколько рабочих процессов ASP.NET, счетчики производительности общего языка (CLR) будут иметь имена, которые напоминают «W3WP#1» или «W3SP#2» и так далее.Это было исправлено в .NET Framework 2.0, чтобы включить счетчик идентификатора процесса в объекте производительности памяти .NET CLR.Этот счетчик отображает идентификатор процесса для экземпляра.Вы можете использовать этот счетчик, чтобы определить счетчик производительности CLR, который связан с процессом.

Также КБ 281884:

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

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

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

Process_PID

Другие советы

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 ...");
}

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

Ник.

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

Я знаю, что на него уже давали ответ, но я публикую это решение только ради полного рабочего кода.Обратите внимание на этот код, основанный на методе, представленном 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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top