Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PerformanceCounter CPU & Memory like Task Manager

I am trying to monitor both CPU and Memory and get matching values (or as close as possible) to TaskManager values. So far I have:

static readonly PerformanceCounter IdleCounter = new PerformanceCounter("Processor", "% Idle Time", "_Total");
static readonly PerformanceCounter RamCounter = new PerformanceCounter("Memory", "Available MBytes");

public string f() {
  return "cpu: " + (100-IdleCounter.NextValue()) + " , ram: " + RamCounter.NextValue() + "MB";
}

This give pretty accurate (as inc comparison to TaskManager) value for cpu, though I would like to get even closer if possible.

For memory however it doesn't seem to match, I get a number but what I really want is a percent like Task Manager shows ..

Any help ?

like image 414
kofifus Avatar asked Jul 18 '18 01:07

kofifus


People also ask

What is _total process?

When the CPU Utilization goes above a critical threshold and has an action configured, A break-up of the CPU Utilization by individual processes list is obtained as a HTML file, which shows the "_Total" attribute which obtained from the performance counter "Process(_Total)\% Processor Time".

What is performance counter in C#?

Performance counters enable us to publish, capture, and analyze the performance data of running code. A performance graph is a two-dimensional plot with one axis indicating time elapsed and the other reporting relevant relative or actual performance statistics.

How do performance counters work?

Windows Performance Counters provide a high-level abstraction layer that provides a consistent interface for collecting various kinds of system data such as CPU, memory, and disk usage. System administrators often use performance counters to monitor systems for performance or behavior problems.


Video Answer


1 Answers

   public string f()

Most important thing to do is sample these performance counters at the same rate as Task Manager does. Particularly so for % Idle Time, a number that has a granularity of 1/64 seconds. Be sure to use a Timer or DispatcherTimer, set its Interval to 1000.

  ... new PerformanceCounter("Processor", "% Idle Time", "_Total")

You need to use a different counter, category "Processor Information". This counter uses a subtly different strategy to measuring performance, it tries to compensate for the unequal behavior of hyper-threaded cores and the side-effects of processor clock frequency throttling. Difference is about ~4% on my machine. Beware that it is hard to get an exact match, the number changes quickly and you are only exactly in sync with Task Manager's sampling times by accident.

  ... new PerformanceCounter("Memory", "Available MBytes")

To convert it to percent you need to subtract this number from the total amount of physical RAM available. You can get this number from ComputerInfo.TotalPhysicalMemory as demonstrated in this post. If you don't want to use this namespace, common complaint, then you have to pinvoke GlobalMemoryStatusEx().

Code I used to verify these changes:

private void timer1_Tick(object sender, EventArgs e) {
    label1.Text = IdleCounter.NextValue().ToString("N0");
    double total = new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory;
    var used = 1024.0 * 1024.0 * RamCounter.NextValue();
    label2.Text = (100.0 * (total - used) / total).ToString("N0");
}
like image 139
Hans Passant Avatar answered Oct 08 '22 12:10

Hans Passant