2008-11-10 48 views
159

Tôi muốn sử dụng tổng CPU tổng thể cho một ứng dụng trong C#. Tôi đã tìm thấy nhiều cách để khai thác các thuộc tính của các quy trình, nhưng tôi chỉ muốn sử dụng CPU của các tiến trình và tổng CPU giống như bạn nhận được trong TaskManager.Cách sử dụng CPU trong C#?

Tôi làm như thế nào?

+1

http://stackoverflow.com/questions/4679962/what-is-the-correct-performance-counter-to-get-cpu-and-memory-usage-of-a-process/4680030 # 4680030 – SwDevMan81

Trả lời

167

Bạn có thể sử dụng lớp PerformanceCounter từ System.Diagnostics.

Initialize như thế này:

PerformanceCounter cpuCounter; 
PerformanceCounter ramCounter; 

cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); 
ramCounter = new PerformanceCounter("Memory", "Available MBytes"); 

Tiêu thụ như thế này:

public string getCurrentCpuUsage(){ 
      return cpuCounter.NextValue()+"%"; 
} 

public string getAvailableRAM(){ 
      return ramCounter.NextValue()+"MB"; 
} 
+74

Đẹp - nhưng th nguồn gốc ban đầu dường như là từ đây: http://zamov.online.fr/EXHTML/CSharp/CSharp_927308.html –

+15

Từ những gì tôi phát hiện ra tôi đã phải sử dụng cpuCounter.NextValue() hai lần và giữa chúng tôi đã phải Ngủ (500) –

+0

Matt đúng. Thậm chí bao gồm cả các lỗi, như quên từ khóa "return". –

5

CMS có điều đó đúng, nhưng còn nếu bạn sử dụng các nhà thám hiểm máy chủ trong visual studio và chơi xung quanh với các tab hiệu suất truy cập sau đó bạn có thể tìm ra cách để có được nhiều chỉ số hữu ích.

9

Bạn có thể sử dụng WMI để nhận thông tin về tỷ lệ phần trăm CPU. Bạn thậm chí có thể đăng nhập vào một máy tính từ xa nếu bạn có quyền chính xác. Hãy xem http://www.csharphelp.com/archives2/archive334.html để biết ý tưởng về những gì bạn có thể thực hiện.

Cũng hữu ích có thể là tham chiếu MSDN cho không gian tên Win32_Process.

Xem thêm ví dụ về CodeProject How To: (Almost) Everything In WMI via C#.

13

OK, tôi hiểu rồi! Cảm ơn bạn đã giúp đỡ!

Đây là đoạn mã để làm điều đó:

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 [email protected]"\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; 
} 
+1

Bạn quên "mới". 'mới ManagementObjectSearcher' ... – SepehrM

51

Một chút hơn được requsted nhưng tôi sử dụng thêm các mã hẹn giờ để theo dõi và cảnh báo nếu sử dụng CPU là 90% trở lên trong một thời gian kéo dài của 1 phút hoặc lâu hơ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 = 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"; 
    } 
} 
+2

getRAMCounter() ở đâu? –

1

Lớp này tự động các cuộc thăm dò quầy mỗi 1 giây và cũng là chủ đề an toàn:

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

'System.DateTime' thực sự là một kiểu giá trị 8 byte có nghĩa là các phép gán cho một biến' DateTime' không phải là nguyên tử. Mã này không phải là luồng an toàn trên nền tảng 32 bit. – andrewjs

18

Sau khi dành một chút thời gian đọc qua một vài bài khác nhau mà có vẻ khá phức tạp tôi đã đưa ra với điều này. Tôi cần nó cho một máy 8 lõi mà tôi muốn theo dõi máy chủ SQL. Đối với mã bên dưới, tôi đã chuyển vào "sqlservr" dưới tên 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); 
     } 
    } 

Dường như đo chính xác% CPU đang được SQL sử dụng trên máy chủ lõi 8 của tôi.

+0

total_cpu phải là PerformanceCounter ("Processor"), không phải PerformanceCounter ("Process") .. nếu không bạn chỉ nhận được 100% * số lõi. –

2

Tôi không thích phải thêm trong gian hàng thứ 1 cho tất cả các giải pháp PerformanceCounter. Thay vào đó, tôi đã chọn sử dụng giải pháp WMI. Lý do chờ đợi/gian hàng thứ 1 tồn tại là cho phép đọc chính xác khi sử dụng PerformanceCounter. Tuy nhiên, nếu bạn gọi phương thức này thường xuyên và làm mới thông tin này, tôi khuyên không nên liên tục phải chịu sự chậm trễ đó ... ngay cả khi nghĩ đến việc thực hiện một quy trình không đồng bộ để có được nó.

tôi bắt đầu với đoạn mã từ đây Returning CPU usage in WMI using C# và thêm một lời giải thích đầy đủ các giải pháp về bài viết trên blog của tôi dưới đây:

Get CPU Usage Across All Cores In C# Using WMI

+1

Giải pháp tuyệt vời và mục nhập blog tuyệt vời! –

3

Điều này dường như làm việc cho tôi, một ví dụ đã chờ đợi cho đến khi đạt đến xử lý một tỷ lệ nhất định

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

tại sao bạn lại ngủ khi sử dụng là 0? – watashiSHUN