Domanda

Ho un Samurizzare config che mostra un grafico di utilizzo della CPU simile a Task Manager.

Come posso visualizzare anche il nome del processo con la percentuale di utilizzo della CPU attualmente più alta?

Vorrei che questo fosse aggiornato, al massimo, una volta al secondo.Samurize può richiamare uno strumento da riga di comando e visualizzarne l'output sullo schermo, quindi anche questa potrebbe essere un'opzione.


Ulteriori chiarimenti:

Ho studiato la scrittura della mia applicazione c# .NET da riga di comando per enumerare l'array restituito da System.Diagnostics.Process.GetProcesses(), ma la classe di istanza Process non sembra includere una proprietà percentuale della CPU.

Posso calcolarlo in qualche modo?

È stato utile?

Soluzione

Con PowerShell:

Get-Process | Sort-Object CPU -desc | Select-Object -first 3 | Format-Table CPU,ProcessName -hidetableheader

restituisce un po' come:

  16.8641632 System
   12.548072 csrss
  11.9892168 powershell

Altri suggerimenti

Quello che vuoi ottenere è l'utilizzo istantaneo della CPU (più o meno) ...

In realtà, l'utilizzo istantaneo della CPU per un processo non esiste.Devi invece fare due misurazioni e calcolare l'utilizzo medio della CPU, la formula è abbastanza semplice:

AvgCpuUsed = [TotalCPUTime(processo,tempo2) - TotalCPUTime(processo,tempo1)] / [tempo2-tempo1]

Minore è la differenza tra Tempo2 e Tempo1, più "istantanea" sarà la misurazione.Il Task Manager di Windows calcola l'utilizzo della CPU con un intervallo di un secondo.Ho scoperto che è più che sufficiente e potresti anche prendere in considerazione l'idea di farlo a intervalli di 5 secondi perché l'atto stesso della misurazione richiede cicli della CPU...

Quindi, innanzitutto, per ottenere il tempo medio della CPU

    using System.Diagnostics;

float GetAverageCPULoad(int procID, DateTme from, DateTime, to)
{
  // For the current process
  //Process proc = Process.GetCurrentProcess();
  // Or for any other process given its id
  Process proc = Process.GetProcessById(procID);
  System.TimeSpan lifeInterval = (to - from);
  // Get the CPU use
  float CPULoad = (proc.TotalProcessorTime.TotalMilliseconds / lifeInterval.TotalMilliseconds) * 100;
  // You need to take the number of present cores into account
  return CPULoad / System.Environment.ProcessorCount;
}

ora, per il carico "istantaneo" della CPU avrai bisogno di una classe specializzata:

 class ProcLoad
{
  // Last time you checked for a process
  public Dictionary<int, DateTime> lastCheckedDict = new Dictionary<int, DateTime>();

  public float GetCPULoad(int procID)
  {
    if (lastCheckedDict.ContainsKey(procID))
    {
      DateTime last = lastCheckedDict[procID];
      lastCheckedDict[procID] = DateTime.Now;
      return GetAverageCPULoad(procID, last, lastCheckedDict[procID]);
    }
    else
    {
      lastCheckedDict.Add(procID, DateTime.Now);
      return 0;
    }
  }
}

Dovresti chiamare quella classe da un timer (o qualsiasi metodo di intervallo che preferisci) per ogni processo che desideri monitorare, se vuoi che tutti i processi usino semplicemente il file Process.GetProcesses metodo statico

Basandosi sulla risposta di Frederic e utilizzando il codice in fondo alla pagina Qui (per un esempio di utilizzo vedi Questo post) per unire l'intero set di processi ottenuti da Get-Process, otteniamo quanto segue:

$sampleInterval = 3

$process1 = Get-Process |select Name,Id, @{Name="Sample1CPU"; Expression = {$_.CPU}}

Start-Sleep -Seconds $sampleInterval

$process2 = Get-Process | select Id, @{Name="Sample2CPU"; Expression = {$_.CPU}}

$samples = Join-Object -Left $process1 -Right $process2 -LeftProperties Name,Sample1CPU -RightProperties Sample2CPU -Where {$args[0].Id -eq $args[1].Id}

$samples | select Name,@{Name="CPU Usage";Expression = {($_.Sample2CPU-$_.Sample1CPU)/$sampleInterval * 100}} | sort -Property "CPU Usage" -Descending | select -First 10 | ft -AutoSize

Il che fornisce un esempio di output

Name                  CPU Usage
----                  ---------
firefox        20.8333333333333
powershell_ise 5.72916666666667
Battle.net               1.5625
Skype                    1.5625
chrome                   1.5625
chrome         1.04166666666667
chrome         1.04166666666667
chrome         1.04166666666667
chrome         1.04166666666667
LCore          1.04166666666667

Potresti essere in grado di utilizzare Pmon.exe per questo.Puoi ottenerlo come parte del file Strumenti del Resource Kit di Windows (il collegamento è alla versione Server 2003, che apparentemente può essere utilizzata anche in XP).

In qualche modo

Get-Process | Sort-Object CPU -desc | Select-Object -first 3 | Format-Table CPU,ProcessName,TotalProcessorTime -hidetableheader

non riceveva le informazioni sulla CPU dal computer remoto.Ho dovuto inventare questo.

Get-Counter '\Process(*)\% Processor Time' | Select-Object -ExpandProperty countersamples | Select-Object -Property instancename, cookedvalue| Sort-Object -Property cookedvalue -Descending| Select-Object -First 10| ft -AutoSize

Grazie per la formula, Jorge.Non capisco bene perché devi dividere per il numero di core, ma i numeri che ottengo corrispondono al Task Manager.Ecco il mio codice PowerShell:

$procID = 4321

$time1 = Get-Date
$cpuTime1 = Get-Process -Id $procID | Select -Property CPU

Start-Sleep -s 2

$time2 = Get-Date
$cpuTime2 = Get-Process -Id $procID | Select -Property CPU

$avgCPUUtil = ($cpuTime2.CPU - $cpuTime1.CPU)/($time2-$time1).TotalSeconds *100 / [System.Environment]::ProcessorCount

Puoi anche farlo in questo modo: -

public Process getProcessWithMaxCPUUsage()
    {
        const int delay = 500;
        Process[] processes = Process.GetProcesses();

        var counters = new List<PerformanceCounter>();

        foreach (Process process in processes)
        {
            var counter = new PerformanceCounter("Process", "% Processor Time", process.ProcessName);
            counter.NextValue();
            counters.Add(counter);
        }
        System.Threading.Thread.Sleep(delay);
        //You must wait(ms) to ensure that the current
        //application process does not have MAX CPU
        int mxproc = -1;
        double mxcpu = double.MinValue, tmpcpu;
        for (int ik = 0; ik < counters.Count; ik++)
        {
            tmpcpu = Math.Round(counters[ik].NextValue(), 1);
            if (tmpcpu > mxcpu)
            {
                mxcpu = tmpcpu;
                mxproc = ik;
            }

        }
        return processes[mxproc];
    }

Utilizzo:-

static void Main()
    {
        Process mxp=getProcessWithMaxCPUUsage();
        Console.WriteLine(mxp.ProcessName);
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top