235

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

我怎么做?

4

10 回答 10

227

您可以使用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";
} 
于 2008-11-10T15:09:36.063 回答
74

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

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";
    }
}
于 2011-05-29T14:54:04.323 回答
21

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

于 2012-08-09T20:06:33.513 回答
16

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;
}
于 2008-11-10T17:07:34.687 回答
9

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

也有帮助的可能是 MSDN 参考Win32_Process

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

于 2008-11-10T15:30:56.847 回答
5

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

于 2008-11-10T15:14:03.590 回答
3

此类每 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;
    }
}
于 2012-04-19T17:03:41.283 回答
2

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

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();
}
于 2013-09-02T13:11:57.643 回答
0

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

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

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

于 2013-07-19T15:07:59.103 回答
0
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();
}

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

于 2020-03-03T20:17:24.917 回答