繁体   English   中英

如何在 C# 中获得每个内核的 CPU 负载?

[英]How can I get CPU load per core in C#?

如何在 C# 中获得每个内核的 CPU 负载(四核 CPU)?

谢谢 :)

您可以使用 WMI 或 System.Diagnostics 命名空间。 从那里你可以获取你想要的任何性能计数器(但是初始化它们需要一秒钟(1-1.5s) - 读取值是可以的,只有初始化很慢)

代码看起来像这样:

    using System.Diagnostics;

    public static Double Calculate(CounterSample oldSample, CounterSample newSample)
    {
        double difference = newSample.RawValue - oldSample.RawValue;
        double timeInterval = newSample.TimeStamp100nSec - oldSample.TimeStamp100nSec;
        if (timeInterval != 0) return 100*(1 - (difference/timeInterval));
        return 0;
    }

    static void Main()
    {
        var pc = new PerformanceCounter("Processor Information", "% Processor Time");
        var cat = new PerformanceCounterCategory("Processor Information");
        var instances = cat.GetInstanceNames();
        var cs = new Dictionary<string, CounterSample>();

        foreach (var s in instances)
        { 
            pc.InstanceName = s;
            cs.Add(s, pc.NextSample());
        }

        while (true)
        {
            foreach (var s in instances)
            {
                pc.InstanceName = s;
                Console.WriteLine("{0} - {1:f}", s, Calculate(cs[s], pc.NextSample()));
                cs[s] = pc.NextSample();
            }
            System.Threading.Thread.Sleep(500);
        }
    }

重要的是,您不能依赖本机 .net 计算 100nsInverse 性能计数器(仅返回 0 或 100 对我来说......错误?)但您必须自己计算它,为此您需要为每个实例的最后一个 CounterSamples 存档(实例代表一个核心或这些核心的总和)。

这些实例似乎有一个命名约定:

0,0 - 第一个 cpu 第一个核心 0,1 - 第一个 cpu 第二个核心 0,_Total - 第一个 cpu 的总负载 _Total - 所有 cpu 的总负载

(未验证 - 在进一步调查完成之前不建议依赖它)...

由于内核显示为操作系统的单独 CPU,因此您可以使用用于确定多处理器机器中每个 CPU 负载的相同代码。 一个这样的例子(在 C 中)是here 请注意,它使用 WMI,因此在上面的评论中链接的另一个线程可能会为您提供大部分方法。

首先,您需要与内核一样多的性能计数器(这需要时间,您可能希望在异步任务中执行此操作,或者它会阻止您的 UI):

CoreCount= Environment.ProcessorCount;
CPUCounters = new PerformanceCounter[CoreCount];
for (var i = 0; i < CoreCount; i++)
    CPUCounters[i] = new PerformanceCounter("Processor", "% Processor Time", $"{i}");

然后你可以获取每个核心的使用值:

public float[] CoreUsage { get; set; } // feel free to implement inpc

public void Update() => CoreUsage = CPUCounters.Select(o => o.NextValue()).ToArray();

但是,您可能想要调用Update()三次:第一次总是得到0.0 ,然后第二次总是0.0100.0 ,最后是实际值。

NextValue()为您提供即时值,而不是随时间变化的平均值; 如果您希望平均值超过 1 秒,您可以使用RawValue并按照此处的说明计算平均值: PerformanceCounter.RawValue 属性

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM