计算UWP应用程序Windows 10 IOT百分比中的CPU使用率

时间:2018-10-26 13:13:47

标签: c# uwp cpu-usage windows-10-iot-core

我想计算CPU使用率百分比。目前,我正在使用ProcessDiagnosticInfo来获取核心时间和用户时间。如何将这段时间转换为百分比,或者建议我找到其他找到它的方法。

private TimeSpan GetTotalCpuTime()
    {
        var totalKernelTime = new TimeSpan();
        var totalUserTime = new TimeSpan();

        var pdis = ProcessDiagnosticInfo.GetForProcesses();
        foreach (var pdi in pdis)
        {
            var cpuUsage = pdi.CpuUsage;
            var report = cpuUsage.GetReport();
            totalKernelTime += report.KernelTime;
            totalUserTime += report.UserTime;
        }

        return totalKernelTime + totalUserTime;
    }

我也知道Windows 10 IoT仪表板API“ / api / resourcemanager / systemperf ”,它返回系统统计信息,其中包括CPU使用率(百分比),但是需要凭据才能访问它,所以我不需要要使用它。

1 个答案:

答案 0 :(得分:1)

每个进程在内核模式下花费一些时间,而在用户模式下花费一些时间。重要的是要注意,我们没有考虑空闲时间。 请参考以下代码。

    private static readonly Stopwatch Stopwatch = new Stopwatch();
    private static TimeSpan _oldElapsed, _oldKernelTime, _oldUserTime;
    private static int ProcessorCount { get; }
    private static double _carryOver;

    static CpuUsage()
    {
        // Stopwatch will be used to track how much time/usage has elapsed.
        Stopwatch.Start();
        // We'll divide the total used CPU time by the number of processors.
        ProcessorCount = System.Environment.ProcessorCount;
        // Run to store the initial "oldKernel/UserTime" so the first read 
        // isn't super inflated by the application's start-up.
        GetTotalCpuTime();
    }

    /// <summary>
    /// Returns the average percentage of CPU time used since the last time this call was made.
    /// </summary>
    /// <returns></returns>
    private static TimeSpan GetTotalCpuTime()
    {
        // Because we could have more than one process running, add all of them up.
        var totalKernelTime = new TimeSpan();
        var totalUserTime = new TimeSpan();

        // Grab the diagnostic infos for all existing processes.
        var pdis = ProcessDiagnosticInfo.GetForProcesses();
        foreach (var pdi in pdis)
        {
            var cpuUsage = pdi.CpuUsage;
            var report = cpuUsage.GetReport();
            totalKernelTime += report.KernelTime;
            totalUserTime += report.UserTime;
        }

        // Subtract the amount of "Total CPU Time" that was previously calculated.
        var elapsedKernelTime = totalKernelTime - _oldKernelTime;
        var elapsedUserTime = totalUserTime - _oldUserTime;

        // Track the "old" variables.
        _oldKernelTime = totalKernelTime;
        _oldUserTime = totalUserTime;

        // Between both is all of the CPU time that's been consumed by the application.
        return elapsedKernelTime + elapsedUserTime;
    }

    public static double GetPercentage()
    {
        // Because there's a small amount of time between when the "elapsed" is grabbed, 
        // and all of the process KernelTime and UserTimes are tallied, the overall CPU
        // usage will be off by a fraction of a percent, but it's nominal.  Like in the 
        // 0.001% range.
        var elapsed = Stopwatch.Elapsed;
        var elapsedTime = elapsed - _oldElapsed;

        var elapsedCpuTime = GetTotalCpuTime();

        // Divide the result by the amount of time that's elapsed since the last check to 
        // get the percentage of CPU time that has been consumed by this application.
        var ret = elapsedCpuTime / elapsedTime / ProcessorCount * 100;

        // Track the "old" variables.
        _oldElapsed = elapsed;

        // This part is completely optional.  Because the thread could be called between 
        // the time that "elapsed" is grabbed, and the CPU times are calculated, this will
        // cause a "pause" that results in spiking the "CPU usage time" over 100%.  However
        // on the next call, the difference will be "lost" (so if it the CPU percent was
        // at 100% for two calls, but this 'pause' happened, one could report 150% while
        // the next would report 50%.)  By carrying over the values above 100%, we can get
        // a slightly more accurate "average" usage.  
        ret += _carryOver;
        if (ret > 100)
        {
            _carryOver = ret - 100;
            ret = 100;
        }
        else
        {
            _carryOver = 0;
        }

        return ret;
    }

更新: 您需要在清单中声明 appDiagnostics packageQuery 功能。

  • appDiagnostics 功能允许应用进行诊断 信息。
  • packageQuery 设备功能允许应用程序执行以下操作: 收集有关其他应用程序的信息。

*。appxmanifest

  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="appDiagnostics" />
    <rescap:Capability Name="packageQuery" />
  </Capabilities>

这是关于blogUWP App Diagnostics,希望对您有所帮助。另外,您可以参考此sample