C # bir uygulama için toplam toplam CPU kullanımı almak istiyorum. İşlemlerin özelliklerini incelemek için birçok yol buldum, ancak yalnızca işlemlerin CPU kullanımını ve TaskManager'da sizin gibi toplam CPU'yu istiyorum.
Bunu nasıl yaparım?
C # bir uygulama için toplam toplam CPU kullanımı almak istiyorum. İşlemlerin özelliklerini incelemek için birçok yol buldum, ancak yalnızca işlemlerin CPU kullanımını ve TaskManager'da sizin gibi toplam CPU'yu istiyorum.
Bunu nasıl yaparım?
Yanıtlar:
Sen kullanabilirsiniz PerformanceCounter gelen sınıf System.Diagnostics .
Bu şekilde başlat:
PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
Bunun gibi tüketin:
public string getCurrentCpuUsage(){
return cpuCounter.NextValue()+"%";
}
public string getAvailableRAM(){
return ramCounter.NextValue()+"MB";
}
Biraz daha fazla requsted ama CPU kullanımı 1 dakika veya daha uzun bir süre boyunca% 90 veya daha yüksek olup olmadığını izlemek ve uyarmak için ekstra zamanlayıcı kodu kullanın.
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
döndürür afloat
. Öyleyse neden a dynamic
? Öyleyse neden bunu dynamic
bir object
? Öyleyse neden object
bir int
satırda bir an atamaya çalışalım int cpuPercent = getCPUCounter()
? (Bu kod derlenmeyecektir.)
Oldukça karmaşık görünen birkaç farklı parçayı okumak için biraz zaman geçirdikten sonra bununla geldim. SQL Server'ı izlemek istediğim 8 çekirdekli bir makineye ihtiyacım vardı. Aşağıdaki kod için "sqlservr" appName olarak geçti.
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 çekirdek sunucumda SQL tarafından kullanılan CPU yüzdesini doğru bir şekilde ölçüyor gibi görünüyor.
done
? Ben bir şey göz ardı sürece, bu sonsuz bir döngü gibi görünüyor:while(!done){...}
Tamam, anladım! Yardımınız için teşekkürler!
İşte bunu yapmak için kod:
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 yüzde bilgisi almak için WMI kullanabilirsiniz. Doğru izinlere sahipseniz uzak bir bilgisayara da giriş yapabilirsiniz. Neleri başarabileceğiniz hakkında fikir edinmek için http://www.csharphelp.com/archives2/archive334.html adresine bakın .
Win32_Process ad alanı için MSDN başvurusu da yararlı olabilir .
Ayrıca CodeProject örneğe bakın C # yoluyla (Neredeyse) Her şeyi In WMI'yı: Nasıl Yapılır .
Bu benim için işe yarıyor gibi görünüyor, işlemci belli bir yüzdeye ulaşana kadar beklemeye bir örnek
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();
}
Bu sınıf sayacı her 1 saniyede bir otomatik olarak yoklar ve ayrıca iş parçacığı için güvenlidir:
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
aslında 8 baytlık bir değer türüdür, yani bir DateTime
değişkene atamalar atomik değildir. Bu kod 32 bit platformlarda iş parçacığı için güvenli değildir.
Tüm PerformanceCounter
çözümlere 1 saniyelik durak eklemek zorunda kalmadım . Bunun yerine bir WMI
çözüm kullanmayı seçtim . 1 saniyelik bekleme / duraklamanın nedeni, a değerini kullanırken okunan değerin doğru olmasını sağlamaktır PerformanceCounter
. Ancak, bu yöntemi sık sık çağırıyor ve bu bilgileri yeniliyorsanız, sürekli olarak bu gecikmeye maruz kalmamanızı tavsiye ederim ... bunu almak için zaman uyumsuz bir işlem yapmayı düşünseniz bile.
Buradan snippet ile başladım C # kullanarak WMI'da CPU kullanımı döndürme ve aşağıdaki blog yazımda çözümün tam bir açıklaması eklendi:
WMI Kullanarak C # İçindeki Tüm Çekirdekler Üzerinde CPU Kullanımı Alın
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();
}
Bu bağlantıdaki orijinal bilgiler https://gavindraper.com/2011/03/01/retrieving-accurate-cpu-usage-in-c/