Answers:
您可以使用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";
}
比要求的要多一点,但是我使用额外的计时器代码来跟踪并发出警报,如果持续1分钟或更长时间,CPU使用率是否达到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";
}
}
cpuCounter.NextValue
返回float
。那么,为什么将其分配给dynamic
?那为什么要把它dynamic
作为一个返回object
呢?那么,为什么要在行中将object
an 分配给an ?(该代码将无法编译。)int
int cpuPercent = getCPUCounter()
花了一些时间阅读了几个看起来很复杂的不同线程后,我想到了这个。我需要用于要监视SQL Server的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);
}
}
看来可以正确衡量我的8核心服务器上SQL使用的CPU百分比。
done
为true?除非我忽略了某些内容,否则这似乎是一个无休止的循环:while(!done){...}
没关系,我知道了!谢谢你的帮助!
这是执行此操作的代码:
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;
}
您可以使用WMI获取CPU百分比信息。如果您具有正确的权限,甚至可以登录到远程计算机。查看http://www.csharphelp.com/archives2/archive334.html,以了解可以完成的工作。
对Win32_Process命名空间的MSDN参考也可能会有所帮助。
另请参见CodeProject示例如何:(几乎)通过C#在WMI中进行所有操作。
这似乎对我有用,例如等待处理器达到一定百分比的示例
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秒自动轮询一次计数器,并且也是线程安全的:
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;
}
}
System.DateTime
实际上是8字节的值类型,这意味着对DateTime
变量的分配不是原子的。此代码在32位平台上不是线程安全的。
我不喜欢在所有PerformanceCounter
解决方案中增加1秒的停顿时间。相反,我选择使用一种WMI
解决方案。1秒等待/停转的原因是为了使使用时的读数准确PerformanceCounter
。但是,如果您经常调用此方法并刷新此信息,则建议不要经常发生这种延迟...即使考虑进行异步处理以获取该延迟。
我从此处的代码片段开始,使用C#返回WMI中的CPU使用率,并在下面的博客文章中添加了对该解决方案的完整说明:
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/