7

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 ?

jjj
  • 1,136
  • 3
  • 18
  • 28
kofifus
  • 17,260
  • 17
  • 99
  • 173
  • 1
    For memory % just query the total ram and divide. https://stackoverflow.com/questions/105031/how-do-you-get-total-amount-of-ram-the-computer-has – mrmichaeldev Jul 18 '18 at 01:44
  • 1
    Here's a cool site on getting CPU by PID. https://weblog.west-wind.com/posts/2014/Sep/27/Capturing-Performance-Counter-Data-for-a-Process-by-Process-Id – mrmichaeldev Jul 18 '18 at 01:46
  • Maybe have a look at https://stackoverflow.com/a/10028263/6730162 – Tobias Brohl Aug 02 '18 at 09:33

2 Answers2

2
   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");
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
-1

You just need to get the total amount of RAM, that is installed on the computer and the RAM that is currently used. Then devide the used RAM with total RAM (used/total) and then multiply it with 100;

If you want to show the used RAM in % you should do something like this:

//Pseudocode
double totalRam = TotalRam();
double ramUsed = RamUsed();
double ramPercentage = ramUsed / totalRam * 100;

With that % value you can even get the RAM that is available in %

double availableRAM = 100 - ramPercentage;
Founntain
  • 13
  • 4