Ottieni nome istanza contatore prestazioni (w3wp # XX) dall'ID processo di lavoro ASP.NET

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

Domanda

Vorrei visualizzare alcune statistiche di memoria (working set, GC, ecc.) su una pagina Web utilizzando i contatori delle prestazioni di .NET / Process. Sfortunatamente, se ci sono più pool di applicazioni su quel server, vengono differenziati usando un indice (# 1, # 2 ecc.) Ma non so come abbinare un ID di processo (che ho) a quell'indice #xx. Esiste un modo programmatico (da una pagina Web ASP.NET)?

È stato utile?

Soluzione

Il primo successo su Google:

Vengono visualizzati più contatori delle prestazioni CLR che hanno nomi simili a " w3wp 1 # "

  

Quando più processi di lavoro ASP.NET   sono in esecuzione, Common Language Runtime   (CLR) avranno i contatori delle prestazioni   nomi che assomigliano a "W3wp # 1" o   "W3sp # 2" e così via. Questo è stato risolto   in .NET Framework 2.0 per includere a   contatore denominato ID processo in .NET   CLR Oggetto prestazioni memoria. Questo   il contatore visualizza l'ID processo per un   esempio. Puoi usare questo contatore per   determinare il contatore delle prestazioni CLR   che è associato a un processo.

Anche KB 281884 :

  

Per impostazione predefinita, Performance Monitor   (Perfmon.msc) visualizza più   processi con lo stesso nome di   enumerando i processi in   seguente modo:

     

Processo n. 1 Processo n. 2 Processo n. 3

     

È inoltre possibile visualizzare Performance Monitor   questi processi aggiungendo il   ID processo (PID) sul nome nel file   seguente modo:

     

Process_PID

Altri suggerimenti

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

L'esempio di chiru non funziona in un caso specifico: quando si hanno due versioni dello stesso programma, denominate uguali, una non è .net e si avvia la versione .net dopo la versione non.net. La versione .Net verrà denominata applicazione n. 1 ma quando si accede ai contatori perf CLR usando questo nome, i nomi di istanza sul contatore hanno il nome senza il numero 1, quindi si ottengono errori.

Nick.

Anche se la modifica delle impostazioni del registro sembra abbastanza facile, sfortunatamente la maggior parte di noi non ha i diritti per farlo sul server (o non vogliamo toccarlo!). In tal caso, esiste una piccola soluzione. Ho scritto un blog su questo qui .

So che ha già ricevuto una risposta, ma per motivi di lavoro completo sto pubblicando questa soluzione. Nota questo codice basato sul metodo presentato da M4N in questa catena:

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

Inoltre, se si desidera ottenere la memoria totale di più istanze dello stesso processo, utilizzare i metodi sopra con quello seguente:

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top