ฉันต้องการรับการใช้งาน CPU ทั้งหมดโดยรวมสำหรับแอปพลิเคชันใน C # ฉันพบหลายวิธีที่จะขุดลงในคุณสมบัติของกระบวนการ แต่ฉันต้องการเพียงการใช้งาน CPU ของกระบวนการและ CPU ทั้งหมดเช่นเดียวกับที่คุณได้รับใน TaskManager
ฉันจะทำอย่างไร
ฉันต้องการรับการใช้งาน CPU ทั้งหมดโดยรวมสำหรับแอปพลิเคชันใน C # ฉันพบหลายวิธีที่จะขุดลงในคุณสมบัติของกระบวนการ แต่ฉันต้องการเพียงการใช้งาน CPU ของกระบวนการและ CPU ทั้งหมดเช่นเดียวกับที่คุณได้รับใน TaskManager
ฉันจะทำอย่างไร
คำตอบ:
คุณสามารถใช้PerformanceCounterระดับจากSystem.Diagnostics
เริ่มต้นเช่นนี้:
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";
}
น้อยกว่าถูก requsted แต่ฉันใช้รหัสตัวจับเวลาพิเศษเพื่อติดตามและแจ้งเตือนหากการใช้งาน 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 = (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
กับ a int
ในบรรทัดint cpuPercent = getCPUCounter()
ทำไม? (รหัสนั้นจะไม่คอมไพล์)
หลังจากใช้เวลาอ่านหัวข้อที่แตกต่างกันสองสามข้อซึ่งดูค่อนข้างซับซ้อนฉันก็คิดเรื่องนี้ ฉันต้องการมันสำหรับเครื่อง 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);
}
}
ดูเหมือนว่าจะวัด% ของ CPU ที่ SQL ใช้อย่างถูกต้องบนเซิร์ฟเวอร์หลัก 8 ตัวของฉัน
done
เป็นจริงที่ไหน ถ้าฉันไม่ได้มองข้ามสิ่งนี้ดูเหมือนว่าจะวนซ้ำไม่รู้จบ: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เพื่อรับทราบว่าคุณสามารถทำอะไรได้บ้าง
นอกจากนี้ยังมีประโยชน์อาจอ้างอิง MSDN สำหรับnamespace Win32_Process
ดูยังมี CodeProject ตัวอย่างวิธีการ: (เกือบ) ทุกอย่างใน WMI ผ่าน C #
CMS นั้นถูกต้อง แต่ถ้าคุณใช้เซิร์ฟเวอร์ explorer ใน 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 วินาทีและยังปลอดภัยต่อเธรด:
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 บิต
ฉันไม่ต้องการเพิ่มในแผงลอย 1 วินาทีเพื่อPerformanceCounter
แก้ปัญหาทั้งหมด ฉันเลือกใช้WMI
วิธีแก้ปัญหาแทน เหตุผลที่ 1 รอสอง / PerformanceCounter
แผงลอยที่มีอยู่คือการช่วยให้การอ่านที่ถูกต้องเมื่อใช้ อย่างไรก็ตามหากคุณโทรหาวิธีนี้บ่อยครั้งและรีเฟรชข้อมูลนี้ฉันไม่แนะนำให้ทำอย่างต่อเนื่องเพื่อให้เกิดความล่าช้านั้น ... แม้ว่าจะคิดว่าจะทำกระบวนการ async เพื่อรับข้อมูลก็ตาม
ฉันเริ่มด้วยตัวอย่างจากที่นี่กลับมาใช้งาน CPU ใน WMI โดยใช้ C #และเพิ่มคำอธิบายแบบเต็มของการแก้ปัญหาในโพสต์บล็อกของฉันด้านล่าง:
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/