C#獲取特定進程CPU和內存使用率

C#獲取特定進程CPU和內存使用率

首先是獲取特定進程對象,可以使用Process.GetProcesses()方法來獲取系統中運行的所有進程,或者使用Process.GetCurrentProcess()方法來獲取當前程序所對應的進程對象。當有了進程對象後,可以通過進程對象名稱來創建PerformanceCounter類型對象,通過設定PerformanceCounter構造函數的參數實現獲取特定進程的CPU和內存使用情況。

具體實例代碼如下:

首先是獲取本機中所有進程對象,分別輸出某一時刻各個進程的內存使用情況:

複製代碼
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Diagnostics;
 6 using System.Threading;
 7 
 8 namespace CSharpPerformance
 9 {//該程序可以實時監控所有進程或者指定進程的工作集、私有工作集
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             //新建一個Stopwatch變量用來統計程序運行時間
15             Stopwatch watch = Stopwatch.StartNew();
16             //獲取本機運行的所有進程ID和進程名,並輸出哥進程所使用的工作集和私有工作集
17             foreach (Process ps in Process.GetProcesses())
18             {
19                 PerformanceCounter pf1 = new PerformanceCounter("Process", "Working Set - Private", ps.ProcessName);
20                 PerformanceCounter pf2 = new PerformanceCounter("Process", "Working Set", ps.ProcessName);
21                 Console.WriteLine("{0}:{1}  {2:N}KB", ps.ProcessName, "工作集(進程類)", ps.WorkingSet64 / 1024);
22                 Console.WriteLine("{0}:{1}  {2:N}KB", ps.ProcessName, "工作集        ", pf2.NextValue() / 1024);
23                 //私有工作集
24                 Console.WriteLine("{0}:{1}  {2:N}KB", ps.ProcessName, "私有工作集    ", pf1.NextValue() / 1024);
25 
26             }
27 
28             watch.Stop();
29             Console.WriteLine(watch.Elapsed);
30             Console.ReadLine();
31         }
32     }
33 }
複製代碼

其中,工作集ps.WorkingSet64是靜態的,pf2.NextValue()是動態變化的,工作集包含進程運行時其獨佔的內存和與其他進程共享的內存的和,而私有工作集是隻包含進程獨佔的內存。

下面一組代碼可以動態顯示本程序所對應的進程的CPU和內存使用率的變化:

首先是SystemInfo.cs類:

複製代碼
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Diagnostics;
  4 using System.Threading;
  5 using System.IO;
  6 using System.Text;
  7 using System.Management;
  8 using System.Runtime.InteropServices;
  9 
 10 namespace CSharpPerformance
 11 {
 12     public class SystemInfo
 13     {
 14         private int m_ProcessorCount = 0;   //CPU個數
 15         private PerformanceCounter pcCpuLoad;   //CPU計數器
 16         private long m_PhysicalMemory = 0;   //物理內存
 17 
 18         private const int GW_HWNDFIRST = 0;
 19         private const int GW_HWNDNEXT = 2;
 20         private const int GWL_STYLE = (-16);
 21         private const int WS_VISIBLE = 268435456;
 22         private const int WS_BORDER = 8388608;
 23 
 24         #region AIP聲明
 25         [DllImport("IpHlpApi.dll")]
 26         extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder);
 27 
 28         [DllImport("User32")]
 29         private extern static int GetWindow(int hWnd, int wCmd);
 30 
 31         [DllImport("User32")]
 32         private extern static int GetWindowLongA(int hWnd, int wIndx);
 33 
 34         [DllImport("user32.dll")]
 35         private static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize);
 36 
 37         [DllImport("user32", CharSet = CharSet.Auto)]
 38         private extern static int GetWindowTextLength(IntPtr hWnd);
 39         #endregion
 40 
 41         #region 構造函數
 42         /// <summary>
 43         /// 構造函數,初始化計數器等
 44         /// </summary>
 45         public SystemInfo()
 46         {
 47             //初始化CPU計數器
 48             pcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total");
 49             pcCpuLoad.MachineName = ".";
 50             pcCpuLoad.NextValue();
 51 
 52             //CPU個數
 53             m_ProcessorCount = Environment.ProcessorCount;
 54 
 55             //獲得物理內存
 56             ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
 57             ManagementObjectCollection moc = mc.GetInstances();
 58             foreach (ManagementObject mo in moc)
 59             {
 60                 if (mo["TotalPhysicalMemory"] != null)
 61                 {
 62                     m_PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString());
 63                 }
 64             }
 65         }
 66         #endregion
 67 
 68         #region CPU個數
 69         /// <summary>
 70         /// 獲取CPU個數
 71         /// </summary>
 72         public int ProcessorCount
 73         {
 74             get
 75             {
 76                 return m_ProcessorCount;
 77             }
 78         }
 79         #endregion
 80 
 81         #region CPU佔用率
 82         /// <summary>
 83         /// 獲取CPU佔用率
 84         /// </summary>
 85         public float CpuLoad
 86         {
 87             get
 88             {
 89                 return pcCpuLoad.NextValue();
 90             }
 91         }
 92         #endregion
 93 
 94         #region 可用內存
 95         /// <summary>
 96         /// 獲取可用內存
 97         /// </summary>
 98         public long MemoryAvailable
 99         {
100             get
101             {
102                 long availablebytes = 0;
103                 //ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PerfRawData_PerfOS_Memory");
104                 //foreach (ManagementObject mo in mos.Get())
105                 //{
106                 //    availablebytes = long.Parse(mo["Availablebytes"].ToString());
107                 //}
108                 ManagementClass mos = new ManagementClass("Win32_OperatingSystem");
109                 foreach (ManagementObject mo in mos.GetInstances())
110                 {
111                     if (mo["FreePhysicalMemory"] != null)
112                     {
113                         availablebytes = 1024 * long.Parse(mo["FreePhysicalMemory"].ToString());
114                     }
115                 }
116                 return availablebytes;
117             }
118         }
119         #endregion
120 
121         #region 物理內存
122         /// <summary>
123         /// 獲取物理內存
124         /// </summary>
125         public long PhysicalMemory
126         {
127             get
128             {
129                 return m_PhysicalMemory;
130             }
131         }
132         #endregion
133 
134         #region 結束指定進程
135         /// <summary>
136         /// 結束指定進程
137         /// </summary>
138         /// <param name="pid">進程的 Process ID</param>
139         public static void EndProcess(int pid)
140         {
141             try
142             {
143                 Process process = Process.GetProcessById(pid);
144                 process.Kill();
145             }
146             catch { }
147         }
148         #endregion
149 
150 
151         #region 查找所有應用程序標題
152         /// <summary>
153         /// 查找所有應用程序標題
154         /// </summary>
155         /// <returns>應用程序標題範型</returns>
156         public static List<string> FindAllApps(int Handle)
157         {
158             List<string> Apps = new List<string>();
159 
160             int hwCurr;
161             hwCurr = GetWindow(Handle, GW_HWNDFIRST);
162 
163             while (hwCurr > 0)
164             {
165                 int IsTask = (WS_VISIBLE | WS_BORDER);
166                 int lngStyle = GetWindowLongA(hwCurr, GWL_STYLE);
167                 bool TaskWindow = ((lngStyle & IsTask) == IsTask);
168                 if (TaskWindow)
169                 {
170                     int length = GetWindowTextLength(new IntPtr(hwCurr));
171                     StringBuilder sb = new StringBuilder(2 * length + 1);
172                     GetWindowText(hwCurr, sb, sb.Capacity);
173                     string strTitle = sb.ToString();
174                     if (!string.IsNullOrEmpty(strTitle))
175                     {
176                         Apps.Add(strTitle);
177                     }
178                 }
179                 hwCurr = GetWindow(hwCurr, GW_HWNDNEXT);
180             }
181 
182             return Apps;
183         }
184         #endregion     
185     }
186 }
複製代碼

然後是執行代碼:

 

複製代碼
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Diagnostics;
 6 using System.Threading;
 7 
 8 namespace CSharpPerformance
 9 {//該程序可以實時監控程序本身對應進程的工作集、私有工作集和CPU使用率
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             //獲取當前進程對象
15             Process cur = Process.GetCurrentProcess();
16 
17             PerformanceCounter curpcp = new PerformanceCounter("Process", "Working Set - Private", cur.ProcessName);
18             PerformanceCounter curpc = new PerformanceCounter("Process", "Working Set", cur.ProcessName);
19             PerformanceCounter curtime = new PerformanceCounter("Process", "% Processor Time", cur.ProcessName);
20 
21             //上次記錄CPU的時間
22             TimeSpan prevCpuTime = TimeSpan.Zero;
23             //Sleep的時間間隔
24             int interval = 1000;
25 
26             PerformanceCounter totalcpu = new PerformanceCounter("Processor", "% Processor Time", "_Total");
27 
28             SystemInfo sys = new SystemInfo();
29             const int KB_DIV = 1024;
30             const int MB_DIV = 1024 * 1024;
31             const int GB_DIV = 1024 * 1024 * 1024;
32             while (true)
33             {
34                 //第一種方法計算CPU使用率
35                 //當前時間
36                 TimeSpan curCpuTime = cur.TotalProcessorTime;
37                 //計算
38                 double value = (curCpuTime - prevCpuTime).TotalMilliseconds / interval / Environment.ProcessorCount * 100;
39                 prevCpuTime = curCpuTime;
40 
41                 Console.WriteLine("{0}:{1}  {2:N}KB CPU使用率:{3}", cur.ProcessName, "工作集(進程類)", cur.WorkingSet64 / 1024,value);//這個工作集只是在一開始初始化,後期不變
42                 Console.WriteLine("{0}:{1}  {2:N}KB CPU使用率:{3}", cur.ProcessName, "工作集        ", curpc.NextValue() / 1024,value);//這個工作集是動態更新的
43                 //第二種計算CPU使用率的方法
44                 Console.WriteLine("{0}:{1}  {2:N}KB CPU使用率:{3}%", cur.ProcessName, "私有工作集    ", curpcp.NextValue() / 1024,curtime.NextValue()/Environment.ProcessorCount);
45                 //Thread.Sleep(interval);
46 
47                 //第一種方法獲取系統CPU使用情況
48                 Console.Write("\r系統CPU使用率:{0}%", totalcpu.NextValue());
49                 //Thread.Sleep(interval);
50 
51                 //第二章方法獲取系統CPU和內存使用情況
52                 Console.Write("\r系統CPU使用率:{0}%,系統內存使用大小:{1}MB({2}GB)", sys.CpuLoad, (sys.PhysicalMemory - sys.MemoryAvailable) / MB_DIV, (sys.PhysicalMemory - sys.MemoryAvailable) / (double)GB_DIV);
53                 Thread.Sleep(interval);
54             }
55 
56             Console.ReadLine();
57         }
58     }
59 }
複製代碼

 

以上程序可以正常運行,沒隔1S刷新一次,實現動態顯示本程序對應進程的CPU和內存使用情況。




.NET(C#):監控CPU使用狀況


 

返回目錄

1. 進程的CPU用戶時間和內核時間

使用Process類的UserProcessorTime和PrivilegedProcessorTime屬性可以返回當前進程所耗費CPU的用戶和內核時間。Process.TotalProcessorTime則代表兩者之和。它們都返回TimeSpan結構體對象。

 

使用這三個屬性,可以做一個簡單的程序進行進程的CPU時間監控。

如下:(當然在CPU不是很慢的情況下,進行某個操作後不會看到明顯的CPU時間增加)

image

 

 

 

返回目錄

2. 全部CPU的使用統計

統計全部CPU的使用狀況,最簡單的方法就是使用Windows的任務管理器程序。但默認是隻顯示“非空閒”執行時間的百分比。在Windows 7任務管理器視圖菜單裏有“顯示內核時間”這一項,這樣的話,用戶時間和內核時間就區分開了。內核時間是紅色部分,如下圖:

image

 

在編程上,使用性能計數器可以進行更詳細的CPU時間監控。比如下面自己做一個CPU使用監控的程序:

image

 

使用的性能計數器是Processor類中的:

  • % Idle Time: 代表空閒
  • % Interrupt Time: 代表處理硬件中斷
  • % User Time: 代表處理用戶指令
  • % Privileged Time: 代表操作系統內核指令
  • % Processor Time: 代表所有非空閒時間(也是任務管理器默認顯示的)

(所有上面的性能計數器返回百分比!)

 

你可以在控制面板的性能監控器中查看這些信息(或者在運行中鍵入:perfmon),如下圖:

image

 

最後需要注意的一點就是PerformaceCounter類(System.Diagnostics命名空間內)的GetNextValue方法進行下一個值的獲取步驟時,雖然該方法返回float,但這個百分比時是已經規格化好的,從0.0到100.0的,而不是0.0到1.0的。

 

返回目錄

3. 源代碼下載

當前版本的程序和源代碼下載
mgen_cpuSample.zip
源代碼環境:Visual C# Express 2010


 


發佈了18 篇原創文章 · 獲贊 37 · 訪問量 98萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章