我试图获得CPU负载,并希望尽可能接近任务管理器中显示的结果。
我第一次尝试使用WMI,它返回一个很好的结果,但速度非常慢(1-10秒就可以完成)。
我现在尝试使用基于代码GetSystemTimes
的here
以下是代码:
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核上)
发布于 2021-08-16 04:06:29
如上所述,使用性能计数器是一个更好的解决方案。
所需的密钥是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();
发布于 2021-08-11 09:05:47
这不是一个完整的答案,但你可能会发现它很有帮助(太长了,不能发表评论)
本文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/
https://stackoverflow.com/questions/68738852
复制相似问题