How can I get CPU load per core in C#?

Solution 1:

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)...