2016-02-12 319 views
4

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

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

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

    } 

这里有两个样本与任务管理器比较。 enter image description here enter image description here

从图中你可以看到我有一个双核CPU和四个逻辑处理器。 CPU是英特尔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?

+0

仍然没有回答,也没有找到工作。 – Padawan256

回答

1

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

+0

如果您注意,一种方法除以二。如果我除以四,那么它唯一的一次匹配率为100%,这将是25%,并且会非常糟糕。所以无论我如何看待它,performanceCounter都是如此。我将研究多个win32_processor对象。 – Padawan256

+0

我认为performanceCounter可以设置为读取每个核心,但据我所知,事情win32_processor读取整个处理器。我没有办法以loadpercentage读取单个内核,因此它似乎应该读取整个CPU负载。但我当然不是专家。 – Padawan256

+0

任何人有任何其他建议? – Padawan256