2012-02-29 31 views
13

Tôi muốn hiển thị mức sử dụng CPU cho ứng dụng đa luồng của tôi (làm việc trên bộ xử lý đa lõi). Tôi muốn nhận được những con số gần với người quản lý công việc. Nhưng tôi có số hơn 100%. Thậm chí hơn 500%. Vâng, tôi biết, hơn truy cập "% Processor Time" cho loại "Process" tôi cần phải chia thành Environment.ProcessorCount hoặc "NumberOfLogicalProcessors" (tương tự cho cấu hình của tôi). Và 500% là kết quả sau hoạt động này. Tôi đã thử nghiệm ví dụ này trên các máy tính khác nhau với phần cứng khác nhau (i7, i5, Core2) và cấu hình phần mềm (Windows 7 SP1 với tất cả các bản cập nhật, Windows 2008 R2 SP1 với tất cả các bản cập nhật) và có cùng một vấn đề.Hiệu năng sử dụng CPU đối với quá trình hiện tại là hơn 100

public static class SystemInfo 
{ 
    private static Process _thisProc; 
    private static bool HasData = false; 
    private static PerformanceCounter _processTimeCounter; 

    private static void Init() 
    { 
     if (HasData) 
      return; 

     if (CheckForPerformanceCounterCategoryExist("Process")) 
     { 
      _processTimeCounter = new PerformanceCounter(); 
      _processTimeCounter.CategoryName = "Process"; 
      _processTimeCounter.CounterName = "% Processor Time"; 
      _processTimeCounter.InstanceName = FindInstanceName("Process"); 
      _processTimeCounter.NextValue(); 
     } 

     MaximumCpuUsageForCurrentProcess = 0; 
     HasData = true; 
    } 

    private static bool CheckForPerformanceCounterCategoryExist(string categoryName) 
    { 
     return PerformanceCounterCategory.Exists(categoryName); 
    } 

    public static string FindInstanceName(string categoryName) 
    { 
     string result = String.Empty; 
     _thisProc = Process.GetCurrentProcess(); 

     if (!ReferenceEquals(_thisProc, null)) 
     { 
      if (!String.IsNullOrEmpty(categoryName)) 
      { 
       if (CheckForPerformanceCounterCategoryExist(categoryName)) 
       { 
        PerformanceCounterCategory category = new PerformanceCounterCategory(categoryName); 
        string[] instances = category.GetInstanceNames(); 
        string processName = _thisProc.ProcessName; 

        if (instances != null) 
        { 
         foreach (string instance in instances) 
         { 
          if (instance.ToLower().Equals(processName.ToLower())) 
          { 
           result = instance; 
           break; 
          } 
         } 
        } 
       } 
      } 
     } 
     return result; 
    } 

    public static int CpuUsageForCurrentProcess 
    { 
     get 
     { 
      Init(); 

      if (!ReferenceEquals(_processTimeCounter, null)) 
      { 
       int result = (int) _processTimeCounter.NextValue(); 
       result /= Environment.ProcessorCount; //NumberOfLogicalProcessors //same for me 

       if (MaximumCpuUsageForCurrentProcess < result) 
        MaximumCpuUsageForCurrentProcess = result; 

       return result; 
      } 
      return 0; 
     } 
    } 

    public static int MaximumCpuUsageForCurrentProcess { private set; get; } 
} 

và mã để thực hiện (bạn cần để tạo ra ứng dụng Windows Forms với hai labeles, một BackgroundWorker và một nút)

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     IList<Task> tasks = new List<Task>(); 
     for (int i = 0; i < 10; i++) 
     { 
      Task t = new Task(() => 
      { 
       do { 
        if (backgroundWorker1.CancellationPending) 
         break; 
       } while (true); 
      }); 
      t.Start(); 
      tasks.Add(t); 
     } 

     Task displayProgress = new Task(() => { do { 
                if (backgroundWorker1.CancellationPending) 
                 break; 
                backgroundWorker1.ReportProgress(1); 
                Thread.Sleep(10); 
               } while (true); }); 
     displayProgress.Start(); 
     tasks.Add(displayProgress); 

     Task.WaitAll(tasks.ToArray()); 
    } 

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     label1.Text = SystemInfo.CpuUsageForCurrentProcess.ToString(); 
     label2.Text = SystemInfo.MaximumCpuUsageForCurrentProcess.ToString(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     label1.Text = SystemInfo.CpuUsageForCurrentProcess.ToString(); 

     if (backgroundWorker1.IsBusy) 
      backgroundWorker1.CancelAsync(); 
     else 
      backgroundWorker1.RunWorkerAsync(); 
    } 

Xin chỉ cho tôi lỗi của tôi. Và vâng, tôi đọc this article và nhận thấy rằng

“\ Process (...) \% Processor Time” có thể lên tới N * 100 (trong đó N là số CPU) bởi vì nó cho biết thêm lên việc sử dụng CPU của quy trình được yêu cầu trên tất cả các CPU.

+1

Vui lòng không sao chép mã lỗ của bạn vào câu hỏi, chỉ là những dòng cần thiết để trả lời câu hỏi của bạn. Và tất nhiên để lại một số ý kiến ​​về mã của bạn. –

Trả lời

4

This (phần nào liên quan) câu hỏi gợi ý sử dụng System.Diagnostics.Process.TotalProcessorTimeSystem.Diagnostics.ProcessThread.TotalProcessorTime tính thay vào đó, đối với chi phí thấp và dễ thực hiện.

(Edit:. Here's an article giải thích làm thế nào để sử dụng tài sản, cũng)

Ngoài ra, có vẻ như bạn không phải chờ đợi đủ lâu giữa các lần gọi "_processTimeCounter.NextValue()." Theo the documentation, bạn phải đợi ít nhất 1 giây. Bạn không chắc liệu điều đó có gây ra những con số kỳ lạ của bạn hay không.

+0

Một sự chậm trễ thứ hai giữa các cuộc gọi cần cho các quầy phụ thuộc vào hai lần đọc. Nhưng giải pháp này hoạt động tốt cho mã của tôi. Về System.Diagnostics.ProcessThread.TotalProcessorTime, tôi đã thử sử dụng giải pháp này trước đây, nhưng có tải CPU lạ (<10%, đó là không hiển thị quá trình tải thực tế). – user809808

+0

Bài viết bạn đề cập đến là tổng lộn xộn: Chương trình ví dụ hiển thị một số giá trị âm. Bản thân việc tính toán liên quan đến việc truy cập quy trình "Nhàn rỗi" vì mục đích không rõ. Tôi chưa bao giờ thấy thông tin gây hiểu lầm nhiều hơn về SO. Điều gì là cơ bản đáng thất vọng mà một số câu trả lời đề cập đến bài viết này. – alehro

Các vấn đề liên quan