17

我一直在尝试放弃使用PerformanceCounter类来监视进程的 CPU 使用率,因为当进程计数变得相当高时(当监视大量进程时),它似乎需要相当多的 CPU。

我的第一种方法是使用Win32_PerfFormattedData_PerfOS_Processor类和 PercentProcessorTime 属性采用 WMI 路由,但是在尝试计算多个内核的 CPU 使用率时似乎存在问题(它返回的最大值是 100%,因此无法根据它进行划分CPU 核心数,导致结果不准确)。

所以最后我决定使用 Process 的类TotalProcessorTime属性。可悲的是,我不确定如何根据该值计算进程使用的总 CPU 使用率的百分比。我知道我应该从以前的 PercentProcessorTime 值中减去当前的 PercentProcessorTime 值,以获得处理器在特定时间限制内花费在进程上的时间,但我不确定如何从那里继续。

提前致谢。

4

2 回答 2

20
class GetCPUUsage
{
    static TimeSpan start;
    public static double CPUUsageTotal
    {
        get;
        private set;
    }

    public static double CPUUsageLastMinute
    {
        get;
        private set;
    }

    static TimeSpan oldCPUTime = new TimeSpan(0);
    static DateTime lastMonitorTime = DateTime.UtcNow;
    public static DateTime StartTime = DateTime.UtcNow;
    // Call it once everything is ready
    static void OnStartup()
    {
        start = Process.GetCurrentProcess().TotalProcessorTime;
    }

    // Call this every 30 seconds
    static void CallCPU()
    {
        TimeSpan newCPUTime = Process.GetCurrentProcess().TotalProcessorTime - start;
        CPUUsageLastMinute = (newCPUTime - oldCPUTime).TotalSeconds / (Environment.ProcessorCount * DateTime.UtcNow.Subtract(lastMonitorTime).TotalSeconds);
        lastMonitorTime = DateTime.UtcNow;
        CPUUsageTotal = newCPUTime.TotalSeconds / (Environment.ProcessorCount * DateTime.UtcNow.Subtract(StartTime).TotalSeconds);
        oldCPUTime = newCPUTime;
    }
}

class GetCPUInfo
{
    public static string GetInfoMinute()
    {
        return String.Format("{0:0.0}", GetCPUUsage.CPUUsageLastMinute * 100);
    }

    public static string GetInfoTotal()
    {
        return String.Format("{0:0.0}", GetCPUUsage.CPUUsageTotal * 100);
    }
}
于 2013-11-03T18:50:06.100 回答
3

基于 111WARLOCK111 的回答,您可以使用以下最少代码来测量当前 CPU 负载:

async Task<double> GetCpuLoadAsync(TimeSpan MeasurementWindow)
{
    Process CurrentProcess = Process.GetCurrentProcess();

    TimeSpan StartCpuTime = CurrentProcess.TotalProcessorTime;
    Stopwatch Timer = Stopwatch.StartNew();

    await Task.Delay(MeasurementWindow);

    TimeSpan EndCpuTime = CurrentProcess.TotalProcessorTime;
    Timer.Stop();

    return (EndCpuTime - StartCpuTime).TotalMilliseconds / (Environment.ProcessorCount * Timer.ElapsedMilliseconds);
}

使用以下代码调用该函数并将 TimeSpan 替换为要监视的窗口:

double CpuLoad = await GetCpuLoadAsync(TimeSpan.FromSeconds(10));
于 2020-02-18T15:34:07.443 回答