我想在c#中获得一个应用程序的总的CPU使用情况。我已经找到了很多方法来深入研究进程的属性,但我只想知道进程的CPU使用情况,以及你在TaskManager中得到的总CPU。

我怎么做呢?


当前回答

对于那些仍然无法获得与任务管理器匹配的CPU使用总数的人,您应该使用以下语句:

new PerformanceCounter("Processor Information", "% Processor Utility", "_Total");

其他回答

您可以使用System.Diagnostics中的PerformanceCounter类。

像这样初始化:

PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;

cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
ramCounter = new PerformanceCounter("Memory", "Available MBytes");

这样消费:

public string getCurrentCpuUsage(){
            return cpuCounter.NextValue()+"%";
}

public string getAvailableRAM(){
            return ramCounter.NextValue()+"MB";
} 

我不喜欢在所有的PerformanceCounter解决方案中添加1秒的停顿。相反,我选择使用WMI解决方案。1秒等待/失速存在的原因是允许在使用PerformanceCounter时读取准确。然而,如果你经常调用这个方法并刷新这个信息,我建议不要经常产生这种延迟…即使考虑做一个异步进程来获得它。

我从这里的代码片段开始,使用c#返回WMI中的CPU使用情况,并在下面的博客文章中添加了解决方案的完整解释:

在c#中使用WMI获取所有核心的CPU使用情况

这个类每1秒自动轮询一次计数器,也是线程安全的:

public class ProcessorUsage
{
    const float sampleFrequencyMillis = 1000;

    protected object syncLock = new object();
    protected PerformanceCounter counter;
    protected float lastSample;
    protected DateTime lastSampleTime;

    /// <summary>
    /// 
    /// </summary>
    public ProcessorUsage()
    {
        this.counter = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public float GetCurrentValue()
    {
        if ((DateTime.UtcNow - lastSampleTime).TotalMilliseconds > sampleFrequencyMillis)
        {
            lock (syncLock)
            {
                if ((DateTime.UtcNow - lastSampleTime).TotalMilliseconds > sampleFrequencyMillis)
                {
                    lastSample = counter.NextValue();
                    lastSampleTime = DateTime.UtcNow;
                }
            }
        }

        return lastSample;
    }
}

CMS是正确的,但如果你使用visual studio中的服务器资源管理器,并摆弄性能计数器选项卡,那么你就可以找到如何获得许多有用的指标。

在花了一些时间阅读了几个看起来相当复杂的不同线程后,我想到了这个。我需要它为一个8核的机器,我想监视SQL server。对于下面的代码,我将“sqlservr”作为appName传入。

private static void RunTest(string appName)
{
    bool done = false;
    PerformanceCounter total_cpu = new PerformanceCounter("Process", "% Processor Time", "_Total");
    PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", appName);
    while (!done)
    {
        float t = total_cpu.NextValue();
        float p = process_cpu.NextValue();
        Console.WriteLine(String.Format("_Total = {0}  App = {1} {2}%\n", t, p, p / t * 100));
        System.Threading.Thread.Sleep(1000);
    }
}

它似乎正确地测量了我的8核服务器上SQL所使用的CPU百分比。