2015-10-28 27 views
12

Ho bisogno di ottenere la memoria RAM e l'utilizzo della CPU durante l'esecuzione di un processo (il processo può essere eseguito a volte e in 30 minuti). Sono in grado di ottenere la RAM libera ma l'utilizzo della CPU non è corretto, rispetto al valore di Task Manager. Sto facendo qualcosa di sbagliato? Qui è il mio codice:Utilizza CPU e RAM

class Program 
{ 
    static List<float> AvailableCPU = new List<float>(); 
    static List<float> AvailableRAM = new List<float>(); 

    protected static PerformanceCounter cpuCounter; 
    protected static PerformanceCounter ramCounter; 
    static void Main(string[] args) 
    { 
     cpuCounter = new PerformanceCounter(); 
     cpuCounter.CategoryName = "Processor"; 
     cpuCounter.CounterName = "% Processor Time"; 
     cpuCounter.InstanceName = "_Total"; 

     ramCounter = new PerformanceCounter("Memory", "Available MBytes"); 

     try 
     { 
      System.Timers.Timer t = new System.Timers.Timer(1200); 
      t.Elapsed += new ElapsedEventHandler(TimerElapsed); 
      t.Start(); 
      Thread.Sleep(10000); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("catched exception"); 
     } 
     Console.ReadLine(); 

    } 

    public static void TimerElapsed(object source, ElapsedEventArgs e) 
    { 
     float cpu = cpuCounter.NextValue(); 
     float ram = ramCounter.NextValue(); 
     Console.WriteLine(string.Format("CPU Value: {0}, ram value: {1}", cpu, ram)); 
     AvailableCPU.Add(cpu); 
     AvailableRAM.Add(ram); 
    } 

} 

Ma quando ho eseguito il programma, ecco quello che è stampato sulla console, rispetto ai valori di task manager: cpu usage

Che cosa sto facendo di sbagliato?

+0

È fluttuante sul display, forse stai confrontando diversi intervalli di tempo? Hai _o_ un valore 2.7 lì ... –

+0

Ho aggiunto un metodo per simulare il carico della CPU ei valori non sono nemmeno vicini a quelli del task manager. Leggo i valori una volta al secondo. Sospetto che ciò possa essere dovuto alla CPU multi core, ma non ne sono ancora sicuro ... –

risposta

6

Non c'è niente di sbagliato con i propri valori.

La ragione che si vede le differenze con quello task manager torna è che il valore di "utilizzo della CPU" è qualcosa di calcolato per un dato intervallo di, vale a dire tra due NextValue() chiamate. Se il task manager "non chiama il proprio NextValue" (se semplifichiamo come funziona) nello stesso momento, non restituirai gli stessi risultati.

Immaginate il seguente scenario:

Time 0: 0% actual CPU usage 
Time 1: 50% actual CPU usage 
Time 2: 70% actual CPU usage 
Time 3: 2% actual CPU usage 
Time 4: 100% actual CPU usage 
  • Se si seleziona il valore tra Ora 1 e Ora 3, tornerete qualcosa sulla base di "50% e il 2%".
  • Se il task manager controlla il valore tra Tempo 2 e Tempo 4, restituirà qualcosa di diverso, cioè un valore basato su "70% e 100%".

Si potrebbe provare a generare più processi della propria applicazione, si dovrebbero anche vedere risultati diversi.

5

Ecco cosa ho trovato: Ho creato una lista con PerformanceCounter oggetti per ogni core, aggiungo la percentuale e dividere il risultato al numero di core fisici:

class Program 
    { 
     static List<float> AvailableCPU = new List<float>(); 
     static List<float> AvailableRAM = new List<float>(); 

     protected static PerformanceCounter cpuCounter; 
     protected static PerformanceCounter ramCounter; 
     static List<PerformanceCounter> cpuCounters = new List<PerformanceCounter>(); 
     static int cores = 0; 
     static void Main(string[] args) 
     { 
      cpuCounter = new PerformanceCounter(); 
      cpuCounter.CategoryName = "Processor"; 
      cpuCounter.CounterName = "% Processor Time"; 
      cpuCounter.InstanceName = "_Total"; 

      foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get()) 
      { 
       cores = cores + int.Parse(item["NumberOfCores"].ToString()); 
      } 

      ramCounter = new PerformanceCounter("Memory", "Available MBytes"); 

      int procCount = System.Environment.ProcessorCount; 
      for(int i = 0; i < procCount; i++) 
      { 
       System.Diagnostics.PerformanceCounter pc = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", i.ToString()); 
       cpuCounters.Add(pc); 
      } 

      Thread c = new Thread(ConsumeCPU); 
      c.IsBackground = true; 
      c.Start(); 

      try 
      { 
       System.Timers.Timer t = new System.Timers.Timer(1200); 
       t.Elapsed += new ElapsedEventHandler(TimerElapsed); 
       t.Start(); 
       Thread.Sleep(10000); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("catched exception"); 
      } 
      Console.ReadLine(); 

     } 

     public static void ConsumeCPU() 
     { 
      int percentage = 60; 
      if (percentage < 0 || percentage > 100) 
       throw new ArgumentException("percentage"); 
      Stopwatch watch = new Stopwatch(); 
      watch.Start(); 
      while (true) 
      { 
       // Make the loop go on for "percentage" milliseconds then sleep the 
       // remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms 
       if (watch.ElapsedMilliseconds > percentage) 
       { 
        Thread.Sleep(100 - percentage); 
        watch.Reset(); 
        watch.Start(); 
       } 
      } 
     } 

     public static void TimerElapsed(object source, ElapsedEventArgs e) 
     { 
      float cpu = cpuCounter.NextValue(); 
      float sum = 0; 
      foreach(PerformanceCounter c in cpuCounters) 
      { 
       sum = sum + c.NextValue(); 
      } 
      sum = sum/(cores); 
      float ram = ramCounter.NextValue(); 
      Console.WriteLine(string.Format("CPU Value 1: {0}, cpu value 2: {1} ,ram value: {2}", sum, cpu, ram)); 
      AvailableCPU.Add(sum); 
      AvailableRAM.Add(ram); 
     } 

    } 

Ecco lo screenshot con i risultati (come si può vedere, il primo metodo è più preciso):

enter image description here