使用GetSystemTimes获取CPU负载



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

我首先尝试使用WMI,它返回一个很好的结果,但非常慢(1-10秒完成。

我现在正试图使用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核上)

  • 我做错了什么?

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

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

本文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/

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

需要的键是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(); 

最新更新