Search code examples
c#asynchronouscpu-usageperformancecounter

Retrieve Cpu usage asynchronously in C#


I want to retrieve the cpu usage of my system using c#. I have read that I must call the method NextValue() then wait for about a second and call the NextValue() method again. I want to do that asynchronous to not delay my UI thread so I have written following code

    public Task<float> GetCpuPerformanceAsync()
    {
        return Task.Run(() =>
        {
            CpuPerformance.NextValue();
            Task.Delay(1000);
            return CpuPerformance.NextValue();
        });
    }

This is the declaration of CpuPerformance

CpuPerformance = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");

At the first time calling the asynchronous method as shown above it returns me the actual cpu usage but then calling it again after few secons it only shows 0 or 100 which doesn't coincide with the usage shown in my task manager

Can somebody help me solving this please?


Solution

  • Unfortunately, dotnetfiddle won't allow me PerformanceCounters, but this should work anyway:

    public class Helper // Of course, you do not necessarily need an extra class ...
    {
        // Lazy Pattern: Will create an instance on first usage.
        private static Lazy<PerformanceCounter> CpuPerformance = new Lazy<PerformanceCounter>(() => {
            // this will be used as factory to create the instance ...
            // 1. create counter
            PerformanceCounter pc = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
            // "warm up"
            pc.NextValue();
            Thread.Sleep(1000);
            // return ready-to-use instance
            return pc;
            // ^^ this will be executed only _once_.
        });
    
        // Read-Only Property uses Lazy to ensure instance exists, then use it.
        public static float CpuTimeInPercent {
            get { return CpuPerformance.Value.NextValue(); }
        }
    }
    

    Usage:

    Console.WriteLine("Performance: {0}%", Helper.CpuTimeInPercent);