WPF MVVM中使用PerformanceCounter获取CPU使用率异常的问题
解决WPF MVVM中CPU使用率显示异常的问题
你的问题核心出在两点:
- 每次调用
GetCPUUsage都新建PerformanceCounter实例,NextValue()首次调用必然返回0——它需要两次采样的差值计算使用率,每次新建都会丢失历史采样数据。 - 若需求是获取系统总CPU使用率,当前使用的
"Process"类别错误,该类别统计的是当前进程的CPU占用,而非系统整体负载;即使是统计当前进程,也需要复用计数器才能得到正确数值。
方案1:获取系统总CPU使用率
修正Utils类(复用计数器+使用正确类别)
将PerformanceCounter改为静态实例,仅初始化一次以保留采样历史:
public static class Utils { // 系统总CPU使用率计数器:类别"Processor",实例"_Total"对应所有核心总和 private static readonly PerformanceCounter _systemCpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); // 静态构造函数中预取一次值,跳过首次调用的无效0值 static Utils() { _systemCpuCounter.NextValue(); } public static string GetSystemCpuUsage() { // 后续调用将返回正确的系统CPU使用率 var cpuUsage = _systemCpuCounter.NextValue(); var formattedUsage = string.Format("{0:N2}%", cpuUsage); Trace.WriteLine($"系统CPU使用率: {formattedUsage}"); return formattedUsage; } }
修正ViewModel中的调用逻辑
private void SetCpuUsageVariable(object sender, EventArgs e) { var systemCpuUsage = Utils.GetSystemCpuUsage(); CpuUsage = $"CPU: {systemCpuUsage}"; }
方案2:获取当前进程的CPU使用率
若需求是统计当前应用自身的CPU占用,按以下方式修正:
修正Utils类(复用进程计数器)
public static class Utils { private static readonly PerformanceCounter _processCpuCounter; static Utils() { // 初始化当前进程的CPU计数器 _processCpuCounter = new PerformanceCounter( "Process", "% Processor Time", Process.GetCurrentProcess().ProcessName); // 预取一次值,跳过首次调用的无效0值 _processCpuCounter.NextValue(); } public static string GetProcessCpuUsage() { // 进程的% Processor Time是所有核心的占用总和,需除以核心数得到单核心占比 var cpuUsage = _processCpuCounter.NextValue() / Environment.ProcessorCount; var formattedUsage = string.Format("{0:N2}%", cpuUsage); Trace.WriteLine($"当前进程CPU使用率: {formattedUsage}"); return formattedUsage; } }
额外优化建议
DispatcherTimer的1秒间隔可以保留,若想更平滑的显示效果,可调整为500毫秒,但过短的采样间隔会增加系统开销,1秒是平衡准确性和性能的合理值。- 注意
PerformanceCounter需要管理员权限才能访问部分系统计数器,若部署时遇到权限问题,需调整应用权限或使用替代方案(如通过System.Diagnostics.Process的TotalProcessorTime自行计算差值)。
内容的提问来源于stack exchange,提问作者Enki
相关产品推荐
相关产品推荐

