質問

私は持っています サムライズ タスクマネージャーと同様のCPU使用率グラフを表示する設定。

現在最も高い CPU 使用率を持つプロセスの名前も表示するにはどうすればよいですか?

これを最大でも 1 秒に 1 回更新したいと考えています。Samurize はコマンド ライン ツールを呼び出し、その出力を画面に表示できるため、これもオプションになる可能性があります。


さらなる解明:

System.Diagnostics.Process.GetProcesses() から返される配列を列挙する独自のコマンド ライン C# .NET アプリケーションの作成を調査しましたが、Process インスタンス クラスには CPU パーセンテージ プロパティが含まれていないようです。

これを何らかの方法で計算することはできますか?

役に立ちましたか?

解決

PowerShell を使用する場合:

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

次のような戻り値を返します。

  16.8641632 System
   12.548072 csrss
  11.9892168 powershell

他のヒント

取得したいのは、瞬間の CPU 使用率 (一種の) です。

実際には、プロセスの瞬間的な CPU 使用率は存在しません。代わりに、2 つの測定を行って平均 CPU 使用率を計算する必要があります。式は非常に簡単です。

AvgCpu Used = [TotalCPUTime(プロセス,time2) - TotalCPUTime(プロセス,time1)] / [time2-time1]

Time2 と Time1 の差が小さいほど、測定はより「即時」になります。Windows タスク マネージャーは、1 秒間隔で CPU 使用量を計算します。これで十分すぎることがわかりました。測定自体が CPU サイクルを消費するため、5 秒間隔で行うことを検討することもできます。

まず、平均 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;
}

ここで、「瞬間的な」CPU 負荷のために、特殊なクラスが必要になります。

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

そのクラスをタイマー (または任意の間隔メソッド) から呼び出す必要があります。 監視したい各プロセス, すべてのプロセスが必要な場合は、 プロセス.GetProcesses 静的メソッド

Frederic の回答に基づいて構築し、ページの下部にあるコードを利用します ここ (使用例については、を参照してください) これ post) から取得したプロセスの完全なセットに参加します Get-Process, 、次の結果が得られます。

$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

これは次の出力例を示します

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

使えるかも知れません Pmon.exe このために。の一部として入手できます。 Windows リソース キット ツール (リンクは Server 2003 バージョンで、XP でも使用できるようです)。

どうにか

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

リモート マシンから CPU 情報を取得していませんでした。これを思いつく必要がありました。

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

公式をありがとう、ホルヘ。なぜコア数で割る必要があるのか​​よくわかりませんが、得られる数値はタスクマネージャーと一致します。私の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

このようにすることもできます:-

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];
    }

使用法:-

static void Main()
    {
        Process mxp=getProcessWithMaxCPUUsage();
        Console.WriteLine(mxp.ProcessName);
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top