CPU 使用率与任务管理器、PerformanceCounter 或 ManagementObjectSearcher 不匹配

Posted

技术标签:

【中文标题】CPU 使用率与任务管理器、PerformanceCounter 或 ManagementObjectSearcher 不匹配【英文标题】:CPU usage does not match Task Manager, PerformanceCounter or ManagementObjectSearcher 【发布时间】:2016-02-12 21:37:00 【问题描述】:

我只是想获得与任务管理器匹配的准确 CPU 使用率。到目前为止,我已经尝试了四种推荐的方法,但都不起作用。

首先,我尝试了我能找到的类似解决方案或建议。这里的代码示例使用了四种方法,均不准确。其次,我知道任务管理器会波动并取决于采样的时间。这仍然不能解释差异。最后,我知道有不同的方法,而任务管理器只使用一种方法。由于这是针对一般用户的,所以需要靠近任务管理器。

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";

    

这里有两个与任务管理器进行比较的示例。

从图中你可以看到我有一个双核 CPU,有四个逻辑处理器。 CPU 是 Intel Skylake i7-6650U,运行 Windows 10。

谢谢

供参考 - 这些链接是相似的: PerformanceCounter reporting higher CPU usage than what's observed How to get the CPU Usage in C#? Calculate CPU usage for a Windows process?

【问题讨论】:

【参考方案1】:

您有 2 个内核但有 4 个线程,因此您需要除以 4,而不是 2。我怀疑您的 WMI 方法只会检查 1 个内核。检查实际上是否有多个win32_processor 对象可用。

【讨论】:

如果您注意到,一种方法确实除以二。如果我除以四,那么它唯一一次以 100% 匹配,它会说 25%,并且会非常糟糕。所以无论我怎么看,performanceCounter 都离我很远。我将研究多个 win32_processor 对象。 我认为 performanceCounter 可以设置为读取每个内核,但据我了解,win32_processor 会读取整个处理器。我看不到用 loadpercentage 读取单个内核的方法,因此它似乎应该读取整个 CPU 负载。不过我当然不是专家。

以上是关于CPU 使用率与任务管理器、PerformanceCounter 或 ManagementObjectSearcher 不匹配的主要内容,如果未能解决你的问题,请参考以下文章

任务管理器中CPU不见了

任务管理器cpu核数更改方法

任务管理器CPU的名字可以改,那CPU的详情信息能不能改?

如何在 任务管理器中 查看某一个进程的cpu占用率?

任务管理器中CPU的内核时间是啥意思

为啥打开任务管理器的时候CPU很高,但是后来又少了是怎么回事