2013-04-19 26 views
5

Tôi cần tính toán mức sử dụng CPU và RAM cho toàn bộ hệ thống cũng như cho một quy trình cụ thể. Tôi chưa bao giờ làm điều này trong C#. Vì vậy, tôi đã có thể đưa ra đoạn mã sau (mà tôi lấy chủ yếu từ các mẫu trên trang web này):Dữ liệu truy cập hiệu suất C# là "trên toàn bản đồ"

try 
{ 
    Process proc = Process.GetCurrentProcess(); 
    string strProcName = proc.ProcessName; 
    Console.WriteLine("Process: " + strProcName); 

    using (PerformanceCounter total_cpu = new PerformanceCounter("Process", "% Processor Time", "_Total", true)) 
    { 
     using (PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", strProcName, true)) 
     { 
      for (; ;) 
      { 
       Console.CursorTop = 1; 
       Console.CursorLeft = 0; 

       float t = total_cpu.NextValue()/Environment.ProcessorCount; 
       float p = process_cpu.NextValue()/Environment.ProcessorCount; 
       Console.WriteLine(String.Format("Total CPU (%) = {0}\t\t\nApp CPU (%) = {1}\t\t\nApp RAM (KB) = {2}", 
        t, p, Process.GetCurrentProcess().WorkingSet64/(1024) 
        )); 

       System.Threading.Thread.Sleep(100); 
      } 
     } 
    } 
} 
catch(Exception ex) 
{ 
    Console.WriteLine("Exception: " + ex); 
} 

Nhưng những gì nó mang lại cho tôi là dữ liệu "trên bản đồ". Hãy xem:

enter image description here

enter image description here

enter image description here

Vì vậy, ai đó có thể trả lời những điểm sau:

  1. Nó có vẻ như chạy như vậy hiệu suất truy cập là một hoạt động khá tốn kém bởi chính nó - nó làm tăng mức sử dụng CPU khoảng 5%. Tôi đã làm một tấn của CPU quầy với C + + và họ mất khá nhiều không có thời gian CPU để chạy.

  2. Bên cạnh những gì tôi đã nói ở trên, lần đầu tiên vòng lặp ở trên chạy với 2 giây trễ! Theo nghĩa đen, bị treo trong 2 giây. Nó có bình thường không? Nếu có, tôi không thể tin rằng họ có một sự táo bạo để gọi nó là bộ đếm hiệu suất :)

  3. Mặc dù đọc RAM của tôi khá gần với báo cáo của Trình quản lý tác vụ, đầu ra CPU là hoàn toàn tắt. Ai đó có thể cho tôi biết tôi đang làm gì sai ở đây?

  4. Hơn nữa, dường như tôi không tìm thấy bất kỳ tài liệu nào cho số PerformanceCounter class, có thể giải thích tất cả các tài liệu sau: % Processor Time, _Total, v.v ...? Và quan trọng nhất, đó chỉ là tiếng Anh? Họ có phải được bản địa hóa không?

  5. Quy trình được chỉ định theo tên của nó. Nhưng nếu tôi có nhiều hơn một quá trình dưới cùng một tên đang chạy. Vậy thì sao?

Trả lời

0

Đây là những gì tôi đã đưa ra, nhưng đó là sử dụng các API không được quản lý:

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool GetProcessTimes(IntPtr hProcess, out System.Runtime.InteropServices.ComTypes.FILETIME 
    lpCreationTime, out System.Runtime.InteropServices.ComTypes.FILETIME lpExitTime, out System.Runtime.InteropServices.ComTypes.FILETIME lpKernelTime, 
    out System.Runtime.InteropServices.ComTypes.FILETIME lpUserTime); 

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.U4)] 
static extern UInt32 GetTickCount(); 

static bool gbSetOldData = false; 
static UInt32 gmsOldTickCount = 0; 
static ulong gnsOldKernelTime = 0; 
static ulong gnsOldUserTime = 0; 

public static double getCPUUsageForProcess(int nProcID = 0) 
{ 
    //Get CPU usage for the process in with ID in 'nProcID' 
    //'nProcID' = process ID, or 0 for the current process 
    //RETURN: 
    //  = CPU usage: [0.0 - 1.0] 
    //  = Negative if error 
    double fCPUUsage = -1.0; 
    try 
    { 
     IntPtr hProcess = nProcID != 0 ? Process.GetProcessById(nProcID).Handle : Process.GetCurrentProcess().Handle; 

     System.Runtime.InteropServices.ComTypes.FILETIME ftCreated, ftExit, ftKernel, ftUser; 
     if (GetProcessTimes(hProcess, out ftCreated, out ftExit, out ftKernel, out ftUser)) 
     { 
      UInt32 dwmsNewTickCount = GetTickCount(); 

      ulong nsNewKernelTime = (ulong)ftKernel.dwHighDateTime; 
      nsNewKernelTime <<= 32; 
      nsNewKernelTime |= (ulong)(uint)ftKernel.dwLowDateTime; 

      ulong nsNewUserTime = (ulong)ftUser.dwHighDateTime; 
      nsNewUserTime <<= 32; 
      nsNewUserTime |= (ulong)(uint)ftUser.dwLowDateTime; 

      if (gbSetOldData) 
      { 
       //Adjust from 100-nanosecond intervals to milliseconds 
       //100-nanosecond intervals = 100 * 10^-9 = 10^-7 
       //1ms = 10^-3 
       fCPUUsage = (double)((nsNewKernelTime - gnsOldKernelTime) + (nsNewUserTime - gnsOldUserTime))/
        (double)((dwmsNewTickCount - gmsOldTickCount) * 10000); 

       //Account for multiprocessor architecture 
       fCPUUsage /= Environment.ProcessorCount; 

       //In case timer API report is inaccurate 
       if (fCPUUsage > 1.0) 
        fCPUUsage = 1.0; 
      } 
      else 
      { 
       //For the first run, assume no CPU usage 
       fCPUUsage = 0.0; 
      } 

      //Remember data 
      gnsOldKernelTime = nsNewKernelTime; 
      gnsOldUserTime = nsNewUserTime; 
      gmsOldTickCount = dwmsNewTickCount; 
      gbSetOldData = true; 
     } 
    } 
    catch 
    { 
     //Failed 
     fCPUUsage = -1.0; 
    } 

    return fCPUUsage; 
} 

Và đây là cách bạn muốn gọi nó là:

int nDummy = 1; 

for (; ;) 
{ 
    double fCPU = getCPUUsageForProcess(); 

    Console.CursorTop = 1; 
    Console.CursorLeft = 0; 

    int nCpu = (int)(fCPU * 100); 
    Console.WriteLine("CPU%: {0}\t\t", nCpu); 

    //Time filler 
    long j = 0; 
    for (; j < 1000000; j++) 
    { 
     nDummy += (int)Math.Cos(1/(j + 1)); 
    } 

    //Don't hog all CPU time! 
    System.Threading.Thread.Sleep(500); 
} 

Tôi không chắc chắn nếu .NET có một phương thức tương tự. Nếu có một (không có tất cả các giới hạn tôi đã đăng ở trên), tôi muốn nghe nó?

0

Mã của bạn có vẻ tốt nhưng tổng số lượt truy cập sử dụng cpu là sai. bạn có quy trình thay vì xử lý. Cũng không chia tỷ lệ phần trăm như thế vì cửa sổ luôn sử dụng cpu có tải ít hơn trừ khi ứng dụng của bạn được tạo cho đa luồng. Điều khác, là mẫu của bạn, nó quá nhanh. Tôi làm chậm nó xuống 1 giây. bạn nên có phản hồi tốt hơn từ bộ đếm

try 
{ 
    Process proc = Process.GetCurrentProcess(); 
    string strProcName = proc.ProcessName; 
    Console.WriteLine("Process: " + strProcName); 

    using (PerformanceCounter total_cpu = new PerformanceCounter("Processor", "% Processor Time", "_Total", true)) 
    { 
     using (PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", strProcName, true)) 
     { 
      for (; ;) 
      { 
       Console.CursorTop = 1; 
       Console.CursorLeft = 0; 

       float t = total_cpu.NextValue() ; 
       float p = process_cpu.NextValue(); 
       Console.WriteLine(String.Format("Total CPU (%) = {0}\t\t\nApp CPU (%) = {1}\t\t\nApp RAM (KB) = {2}", 
        t, p, Process.GetCurrentProcess().WorkingSet64/(1024) 
        )); 

       System.Threading.Thread.Sleep(1000); 
      } 
     } 
    } 
} 
catch(Exception ex) 
{ 
    Console.WriteLine("Exception: " + ex); 
} 
Các vấn đề liên quan