如何在c#中获取CPU的使用情况?

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

我怎么做呢?

336261 次浏览

你可以从系统。诊断中使用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";
}

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

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

Win32_Process命名空间的MSDN引用也有帮助。

另见CodeProject示例如何:(几乎)一切在WMI通过c#

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

下面是代码:

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

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

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

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

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

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

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

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

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

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

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