6

I am just trying to get accurate CPU usage that matches Task Manager. So far I have tried four recommended methods that do not work.

First, I have tried the similar solutions or suggestions given that I could find. The code sample here uses four methods, all of which are inaccurate. Second, I know that Task Manager fluctuates and depends on when it is sampled. That still does not account for the differences. Lastly, I know there are different methods, and that Task Manager uses just one method. Since this is intended for general users, it needs to be close to Task Manager.

public partial class MainWindow : Window
{
    //*** Method 1 & 2
    PerformanceCounter cpuCounterPi = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
    PerformanceCounter cpuCounterP = new PerformanceCounter("Processor", "% Processor Time", "_Total");

    //*** method 3
    ManagementObjectSearcher query1 = new ManagementObjectSearcher("select loadpercentage from win32_processor");

    //*** Mixed method usage below
    CounterSample csPi1, csPi2, csP1, csP2;
    double cpuPercentagePi, cpuPercentageP, cpuPercentageLoad;
    int count = -1;
    Boolean alternate = false;

    System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();

    public MainWindow()
    {
        InitializeComponent();

        dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
        dispatcherTimer.Interval = new TimeSpan(0, 0, 5);
        dispatcherTimer.Start();
    }

    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        count++;
        //***Method 1 & 2
        if (alternate)
        {
            csPi1 = cpuCounterPi.NextSample();
            cpuPercentagePi = CounterSample.Calculate(csPi2, csPi1);
            csP1 = cpuCounterP.NextSample();
            cpuPercentageP = CounterSample.Calculate(csP2, csP1);

        }
        else
        {
            csPi2 = cpuCounterPi.NextSample();
            cpuPercentagePi = CounterSample.Calculate(csPi1, csPi2);
            csP2 = cpuCounterP.NextSample();
            cpuPercentageP = CounterSample.Calculate(csP1, csP2);
        }
        alternate = !alternate;

        if (count==5) { textBox.Clear(); count = 0; }
        textBox.Text = textBox.Text + "\nProcessor Information (Method 1)         " + cpuPercentagePi.ToString();
        textBox.Text = textBox.Text + "\nProcessor  (Method 2)                          " + cpuPercentageP.ToString();
        textBox.Text = textBox.Text + "\nProcessor ½  (Method 2 divided by 2)   " + (cpuPercentageP/2).ToString();
        //*****  Method 3 ****
        ManagementObjectCollection cpuColl = query1.Get();
        foreach (ManagementObject mo in cpuColl)
        {
            cpuPercentageLoad = Convert.ToDouble(mo["loadpercentage"]);
        }
        textBox.Text = textBox.Text +  "\nProcessor Load  (Method 3)                " + cpuPercentageLoad.ToString() + "\n";

    }

Here are two samples comparing to task manager. enter image description here enter image description here

From the picture you can see I have a dual core CPU, with four logical processors. The CPU is a Intel Skylake i7-6650U, running Windows 10.

Thanks

For reference - These links are similar: PerformanceCounter reporting higher CPU usage than what's observed How to get the CPU Usage in C#? Calculate CPU usage for a Windows process?

Community
  • 1
  • 1
Padawan256
  • 103
  • 1
  • 5

1 Answers1

1

You have 2 cores but 4 threads, so you need to divide by 4, not 2. Also your WMI method I suspect will only be checking 1 core. Check if there are in fact multiple win32_processor objects available.

PhonicUK
  • 13,486
  • 4
  • 43
  • 62
  • If you notice, one method does divide by two. If I divide by four, then the only time it matches at 100%, it will say 25% and will be horribly off. So no matter how I look at it, performanceCounter is way off. I will look into the multiple win32_processor objects. – Padawan256 Feb 13 '16 at 02:43
  • I think performanceCounter can be set to read each core, but as I understand things win32_processor reads the entire processor. I see no way to read individual cores with loadpercentage, thus it seems it should read entire CPU load.. I am certainly not an expert at all though. – Padawan256 Feb 13 '16 at 10:51