c# - 让 WMI 更快地读取处理器负载

标签 c# load wmi performancecounter processor

我有一个 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/

相关文章:

c# - 延迟加载转发器有 linq 查询不产生结果

c# - 隐藏和显示面板的Javascript代码

c++ - 作为服务运行时连接到远程机器的 WMI

powershell - 使用PowerShell卸载ClickOnce应用程序?

c# - 是否可以将两种类型的对象传递给 Restsharp?

c# - EF 5 外键名称

javascript - 使用 get() 加载页面之前加载图像

javascript - 在通过 jQuery 的 load() 函数加载的 HTML 上使用已经加载的 JS?

jQuery ajax 问题,堆叠 div

c# - EventQuery 中的 ISA 是什么?