【问题标题】:Get CPU load using GetSystemTimes使用 GetSystemTimes 获取 CPU 负载
【发布时间】:2021-08-11 08:51:25
【问题描述】:

我正在尝试获取 CPU 负载,并希望尽可能接近任务管理器中显示的结果。

我第一次尝试使用 WMI,它返回了一个很好的结果,但速度非常慢(1-10 秒才能完成。

我现在正在尝试基于代码here使用GetSystemTimes

代码如下:

  static class ProcessorLogic {
    // calc cpu
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool GetSystemTimes(out FILETIME lpIdleTime, out FILETIME lpKernelTime, out FILETIME lpUserTime);

    static bool bUsedOnce = false;
    static ulong uOldIdle = 0;
    static ulong uOldKrnl = 0;
    static ulong uOldUsr = 0;

    public static int CPUusagePercent() {
      int nRes = -1;

      if (GetSystemTimes(out FILETIME ftIdle, out FILETIME ftKrnl, out FILETIME ftUsr)) {
        ulong uIdle = ((ulong)ftIdle.dwHighDateTime << 32) | (uint)ftIdle.dwLowDateTime;
        ulong uKrnl = ((ulong)ftKrnl.dwHighDateTime << 32) | (uint)ftKrnl.dwLowDateTime;
        ulong uUsr = ((ulong)ftUsr.dwHighDateTime << 32) | (uint)ftUsr.dwLowDateTime;

        if (bUsedOnce) {
          ulong uDiffIdle = uIdle - uOldIdle;
          ulong uDiffKrnl = uKrnl - uOldKrnl;
          ulong uDiffUsr = uUsr - uOldUsr;

          if ((uDiffKrnl + uDiffUsr) != 0) { //Calculate percentage
            nRes = (int)((uDiffKrnl + uDiffUsr - uDiffIdle) * 100 / (uDiffKrnl + uDiffUsr));
          }
        }

        bUsedOnce = true;
        uOldIdle = uIdle;
        uOldKrnl = uKrnl;
        uOldUsr = uUsr;
      }

      return nRes;
    }
  }

我得到的结果大约是任务管理器上显示的结果的 40%(在 Intel(R) Core(TM) i7-10850H 2.70GHz 6 核上运行)

  • 我做错了什么?

  • 我觉得我在这里重新发明轮子,是否有可靠的库/项目/代码来正确获得这些结果?

【问题讨论】:

标签: c#


【解决方案1】:

这不是一个完整的答案,但您可能会发现它很有帮助(评论太长)

本文https://www.codeproject.com/Articles/9113/Get-CPU-Usage-with-GetSystemTimes

但在结论中它说:

还有一个问题。对于多处理器系统,您不需要 有正确的信息。

所以你也可以看看这篇文章,虽然它不在 C# 中,但它应该仍然对你有帮助,可以帮助你。例如,它还谈到了一个未记录的 NtQuerySystemInformation 函数。

https://www.autoitscript.com/forum/topic/151831-cpu-multi-processor-usage-wo-performance-counters/

【讨论】:

    【解决方案2】:

    如上所述,使用性能计数器是一个更好的解决方案

    需要的密钥是Processor Information, % Processor Utility & _Total

    var PerformanceCounterCPULoad = new PerformanceCounter("Processor Information", "% Processor Utility", "_Total");
    
    // call this every second or so
    var percent = (int)PerformanceCounterCPULoad.NextValue(); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-01
      • 2011-04-10
      • 1970-01-01
      • 2017-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多