我有一个 C# 应用程序,我必须在其中获取处理器负载。根据 this 接受的答案问题,我的选择是使用 WMI 或 System.Diagnostics 命名空间中的性能计数器。我的 System.Diagnostics 性能计数器有问题(如记录的 here ),所以我唯一的选择是使用 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 对象仅更新处理器加载属性,但我不知道该怎么做。
顺便说一句,奇怪的是输出的采样时间在半秒左右如此稳定,但我不确定这是否可以为解决方案提供任何提示。
最佳答案
一定要慢,没有其他办法。 CPU 内核要么全速运行,要么被 HALT 指令关闭。从中它被中断再次唤醒。有效 CPU 负载是在一段时间内(通常为一秒)计算出的平均值。运行时间除以周期。
如果您缩短周期,则计算值的准确度会降低。如果太短,数字就会在 0 到 100 之间跳跃。
据我所知,您无法更改 WMI 查询中的采样率。您可以通过直接读取性能计数器来获得更快(且噪音更大)的更新。您可以在我的回答中找到示例代码 this thread .
关于c# - 让 WMI 更快地读取处理器负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3524921/