You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF MVVM中使用PerformanceCounter获取CPU使用率异常的问题

解决WPF MVVM中CPU使用率显示异常的问题

你的问题核心出在两点:

  1. 每次调用GetCPUUsage都新建PerformanceCounter实例,NextValue()首次调用必然返回0——它需要两次采样的差值计算使用率,每次新建都会丢失历史采样数据。
  2. 若需求是获取系统总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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:30:53