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

我想获得C#中的应用程序总的CPU使用率。 我已经找到了很多方法来挖掘进程的属性,但是我只想要进程的CPU使用情况,以及像TaskManager一样的CPU总数。

我怎么做?

您可以使用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"; } 

稍微多一点的要求,但我使用额外的计时器代码来跟踪和警报,如果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 = 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"; } } 

花了一些时间阅读了几个不同的线程,看起来很复杂,我想出了这个。 我需要它的一个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的百分比。

没关系,我明白了! 谢谢你的帮助!

这是执行它的代码:

 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 = 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; } 

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

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

另请参阅CodeProject示例如何:(几乎)通过C#在WMI中的所有内容 。

CMS是正确的,但是,如果您在Visual Studio中使用服务器资源管理器,并使用性能计数器选项卡,则可以计算出如何获得大量有用的度量标准。

这似乎对我来说是一个等待处理器达到一定比例的例子

 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(); } 

我不喜欢在1秒内添加所有PerformanceCounter解决方案。 相反,我选择了使用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; } }