How can I get CPU Load per core (quadcore cpu), in C#?
You can either use WMI or the System.Diagnostics namespace. From there you can grab any of the performance counters you wish (however it takes a second (1-1.5s) to initialize those - reading values is ok, only initialization is slow)
Code can look then like this:
using System.Diagnostics;
public static Double Calculate(CounterSample oldSample, CounterSample newSample)
{
double difference = newSample.RawValue - oldSample.RawValue;
double timeInterval = newSample.TimeStamp100nSec - oldSample.TimeStamp100nSec;
if (timeInterval != 0) return 100*(1 - (difference/timeInterval));
return 0;
}
static void Main()
{
var pc = new PerformanceCounter("Processor Information", "% Processor Time");
var cat = new PerformanceCounterCategory("Processor Information");
var instances = cat.GetInstanceNames();
var cs = new Dictionary<string, CounterSample>();
foreach (var s in instances)
{
pc.InstanceName = s;
cs.Add(s, pc.NextSample());
}
while (true)
{
foreach (var s in instances)
{
pc.InstanceName = s;
Console.WriteLine("{0} - {1:f}", s, Calculate(cs[s], pc.NextSample()));
cs[s] = pc.NextSample();
}
System.Threading.Thread.Sleep(500);
}
}
Important thing is that you cant rely on native .net calculation for 100nsInverse performance counters (returns only 0 or 100 for me ... bug?) but you have to calculate it yourself and for that you need an archive of last CounterSamples for each instance (instances represent a core or a sum of those cores).
There appears to be a naming convetion for those instances :
0,0 - first cpu first core 0,1 - first cpu second core 0,_Total - total load of first cpu _Total - total load of all cpus
(not verified - would not recommend to rely on it untill further investigation is done)...
NextValue()
computes the result from NextSample()
. First result is 0, second is 0 or 100%, the third is the actual value, hence "only 0 or 100" is not a bug. –
Barrault Calculate
is wrong. You might want to use GetValue()
instead of GetSample()
and then calculate. –
Barrault Since cores show up as seperate CPUs to the OS, you use the same code you'd use to determine the load per CPU in a multiprocessor machine. One such example (in C) is here. Note that it uses WMI, so the other thread linked in the comments above probably has you most of the way there.
First you need as many performance counters as cores (it takes time, you might want to do this in an async task, or it blocks you UI):
CoreCount= Environment.ProcessorCount;
CPUCounters = new PerformanceCounter[CoreCount];
for (var i = 0; i < CoreCount; i++)
CPUCounters[i] = new PerformanceCounter("Processor", "% Processor Time", $"{i}");
Then you can fetch the value of usage of each core:
public float[] CoreUsage { get; set; } // feel free to implement inpc
public void Update() => CoreUsage = CPUCounters.Select(o => o.NextValue()).ToArray();
However you might want to call Update()
three times: the first time you'll always get 0.0
, then second time always 0.0
or 100.0
, and then at last the actual value.
NextValue()
gives you the instant value, not the mean value over time; if you want the mean value say over 1 second, you can use RawValue
and calculate the mean as explained here: PerformanceCounter.RawValue Property
© 2022 - 2024 — McMap. All rights reserved.