我有一个C#应用程序,我必须得到处理器负载。根据{{3}}问题的接受答案,我的选择是使用来自WMI或System.Diagnostics名称空间的性能计数器。我有System.Diagnostics性能计数器的问题(如文档this所示),所以我唯一的选择是使用WMI。以下代码显示了我如何使用WMI读取处理器负载:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
namespace ProcessorUtilizationSpike
{
class Program
{
private static ManagementObject processor;
static void Main(string[] args)
{
processor = new ManagementObject("Win32_PerfFormattedData_PerfOS_Processor.Name='_Total'");
while(true)
{
PrintTimedMeasure();
}
}
static void PrintTimedMeasure()
{
DateTime start = DateTime.Now;
UInt64 wmi = WMIMeasure();
DateTime stop = DateTime.Now;
Console.WriteLine("wmi : " + wmi + ", time: " + (stop - start));
}
static UInt64 WMIMeasure()
{
processor.Get();
return ((UInt64)processor.Properties["PercentProcessorTime"].Value); // this property corresponds to a UInt64, see the Type property.
}
}
}
我的问题是,检索处理器利用率需要大约半秒钟,从这个典型的输出片段可以看出:
wmi : 6, time: 00:00:00.5156250
wmi : 3, time: 00:00:00.5156250
wmi : 4, time: 00:00:00.5000000
wmi : 3, time: 00:00:00.5156250
wmi : 3, time: 00:00:00.5000000
我的猜测是,至少部分原因是,加载样本需要很长时间,Get方法调用还会更新ManagementObject对象的其他属性。所以我的问题是:如何让Get方法调用更新更快?我猜,解决方案是以某种方式告诉ManagementObject对象只更新处理器负载属性,但我不知道如何做到这一点。
顺便说一下,很奇怪输出的采样时间在半秒左右是如此稳定,但我不确定这是否可以给出解决方案的任何提示。
答案 0 :(得分:3)
它必须缓慢,没有别的办法。 CPU内核要么以全通道运行,要么通过HALT指令关闭。通过中断再次唤醒它。有效CPU负载是在一段时间内计算的平均值,通常为一秒。它运行的时间除以周期。
如果您将周期缩短,则计算值会变得不准确。使它太短,数字将在0到100之间跳跃。
您无法在WMI查询中更改采样率。通过直接读取性能计数器,您可以获得更快(更嘈杂)的更新。您可以在this thread中的答案中找到示例代码。
答案 1 :(得分:2)
建议:使用Win32_PerfRawData_PerfOS_Processor性能计数器和PERF_100NSEC_TIMER_INV算法代替格式化计数器。舍入可能会导致一些相当不准确的结果。