如何在 C# 中获取 CPU 使用率?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/278071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 21:15:22  来源:igfitidea点击:

How to get the CPU Usage in C#?

c#cpu-usage

提问by

I want to get the overall total CPU usage for an application in C#. I've found many ways to dig into the properties of processes, but I only want the CPU usage of the processes, and the total CPU like you get in the TaskManager.

我想在 C# 中获取应用程序的总体 CPU 使用率。我找到了很多方法来挖掘进程的属性,但我只想要进程的 CPU 使用率,以及像你在 TaskManager 中得到的总 CPU。

How do I do that?

我怎么做?

回答by CMS

You can use the PerformanceCounterclass from System.Diagnostics.

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

Initialize like this:

像这样初始化:

PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;

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

Consume like this:

像这样消费:

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

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

回答by Tarks

CMS has it right, but also if you use the server explorer in visual studio and play around with the performance counter tab then you can figure out how to get lots of useful metrics.

CMS 是正确的,但如果您在 Visual Studio 中使用服务器资源管理器并使用性能计数器选项卡,那么您可以弄清楚如何获得许多有用的指标。

回答by adparadox

You can use WMI to get CPU percentage information. You can even log into a remote computer if you have the correct permissions. Look at http://www.csharphelp.com/archives2/archive334.htmlto get an idea of what you can accomplish.

您可以使用 WMI 获取 CPU 百分比信息。如果您拥有正确的权限,您甚至可以登录远程计算机。查看http://www.csharphelp.com/archives2/archive334.html以了解您可以完成的工作。

Also helpful might be the MSDN reference for the Win32_Processnamespace.

同样有用的可能是Win32_Process命名空间的 MSDN 参考。

See also a CodeProject example How To: (Almost) Everything In WMI via C#.

另请参阅 CodeProject 示例How To: (Almost) Everything In WMI via C#

回答by xoxo

It's OK, I got it! Thanks for your help!

没关系,我知道了!谢谢你的帮助!

Here is the code to do it:

这是执行此操作的代码:

private void button1_Click(object sender, EventArgs e)
{
    selectedServer = "JS000943";
    listBox1.Items.Add(GetProcessorIdleTime(selectedServer).ToString());
}

private static int GetProcessorIdleTime(string selectedServer)
{
    try
    {
        var searcher = new
           ManagementObjectSearcher
             (@"\"+ selectedServer +@"\root\CIMV2",
              "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name=\"_Total\"");

        ManagementObjectCollection collection = searcher.Get();
        ManagementObject queryObj = collection.Cast<ManagementObject>().First();

        return Convert.ToInt32(queryObj["PercentIdleTime"]);
    }
    catch (ManagementException e)
    {
        MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
    }
    return -1;
}

回答by Khalid Rahaman

A little more than was requsted but I use the extra timer code to track and alert if CPU usage is 90% or higher for a sustained period of 1 minute or longer.

比要求的多一点,但我使用额外的计时器代码来跟踪和提醒 CPU 使用率是否为 90% 或更高并持续 1 分钟或更长时间。

public class Form1
{

    int totalHits = 0;

    public object getCPUCounter()
    {

        PerformanceCounter cpuCounter = new PerformanceCounter();
        cpuCounter.CategoryName = "Processor";
        cpuCounter.CounterName = "% Processor Time";
        cpuCounter.InstanceName = "_Total";

                     // will always start at 0
        dynamic firstValue = cpuCounter.NextValue();
        System.Threading.Thread.Sleep(1000);
                    // now matches task manager reading
        dynamic secondValue = cpuCounter.NextValue();

        return secondValue;

    }


    private void Timer1_Tick(Object sender, EventArgs e)
    {
        int cpuPercent = (int)getCPUCounter();
        if (cpuPercent >= 90)
        {
            totalHits = totalHits + 1;
            if (totalHits == 60)
            {
                Interaction.MsgBox("ALERT 90% usage for 1 minute");
                totalHits = 0;
            }                        
        }
        else
        {
            totalHits = 0;
        }
        Label1.Text = cpuPercent + " % CPU";
        //Label2.Text = getRAMCounter() + " RAM Free";
        Label3.Text = totalHits + " seconds over 20% usage";
    }
}

回答by Colin Breame

This class automatically polls the counter every 1 seconds and is also thread safe:

这个类每 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;
    }
}

回答by MtnManChris

After spending some time reading over a couple different threads that seemed pretty complicated I came up with this. I needed it for an 8 core machine where I wanted to monitor SQL server. For the code below then I passed in "sqlservr" as appName.

在花了一些时间阅读了几个看起来很复杂的不同线程后,我想出了这个。我需要它用于我想监视 SQL 服务器的 8 核机器。对于下面的代码,我将“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);
    }
}

It seems to correctly measure the % of CPU being used by SQL on my 8 core server.

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

回答by atconway

I did not like having to add in the 1 second stall to all of the PerformanceCountersolutions. Instead I chose to use a WMIsolution. The reason the 1 second wait/stall exists is to allow the reading to be accurate when using a PerformanceCounter. However if you calling this method often and refreshing this information, I'd advise not to constantly have to incur that delay... even if thinking of doing an async process to get it.

我不喜欢必须在所有PerformanceCounter解决方案中添加 1 秒的停顿。相反,我选择使用WMI解决方案。存在 1 秒等待/停顿的原因是为了在使用PerformanceCounter. 但是,如果您经常调用此方法并刷新此信息,我建议您不要经常发生这种延迟......即使考虑执行异步过程来获取它。

I started with the snippet from here Returning CPU usage in WMI using C#and added a full explanation of the solution on my blog post below:

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

Get CPU Usage Across All Cores In C# Using WMI

使用 WMI 获取 C# 中所有内核的 CPU 使用率

回答by Jay Byford-Rew

This seems to work for me, an example for waiting until the processor reaches a certain percentage

这似乎对我有用,一个等待处理器达到一定百分比的例子

var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
int usage = (int) cpuCounter.NextValue();
while (usage == 0 || usage > 80)
{
     Thread.Sleep(250);
     usage = (int)cpuCounter.NextValue();
}

回答by araad1992

public int GetCpuUsage()
{
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total", Environment.MachineName);
cpuCounter.NextValue();
System.Threading.Thread.Sleep(1000); //This avoid that answer always 0
return (int)cpuCounter.NextValue();
}

Original information in this link https://gavindraper.com/2011/03/01/retrieving-accurate-cpu-usage-in-c/

此链接中的原始信息https://gavindraper.com/2011/03/01/retrieving-accurate-cpu-usage-in-c/