CPU Usage (C#) 测试

注意:算法仅供参考。

cpuusage.cs

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Diagnostics;
  4 using System.IO;
  5 using System.Linq;
  6 using System.Text;
  7 using System.Threading;
  8 
  9 namespace cpuusage
 10 {
 11     class Program
 12     {
 13         const string VERSION = "cpuusage v0.1.0";
 14         static readonly Dictionary<string, PerformanceCounter> _caches = new Dictionary<string, PerformanceCounter>();
 15         static string _format = "list";
 16         static int _sleep = 1000;
 17         static int _times = -1;
 18         static bool _pauseWhenFinish = false;
 19         static StreamWriter  _sw = null;
 20         static bool _listProcessNames = false;
 21         static bool _printUsage = false;
 22         static bool _printVersion = false;
 23 
 24         static void Main(string[] args)
 25         {
 26             var processNames = GetProcessNamesAndParseArgs(args);
 27             if (_printVersion)
 28             {
 29                 PrintVersion();
 30             }
 31             if (_printUsage)
 32             {
 33                 PrintUsage();
 34             }
 35             else if (_listProcessNames)
 36             {
 37                 PrintProcessNames(processNames);
 38             }
 39             else
 40             {
 41                 switch (_format)
 42                 {
 43                     case "table":
 44                         PrintToTable(processNames);
 45                         break;
 46                     case "csv":
 47                         PrintToCsv(processNames);
 48                         break;
 49                     case "list":
 50                         PrintToList(processNames);
 51                         break;
 52                     default:
 53                         Fault(1, "ERROR: -f argument error");
 54                         break;
 55                 }
 56             }
 57             if (_pauseWhenFinish) {
 58                 Console.WriteLine();
 59                 Console.Write("Press any key to EXIT...");
 60                 Console.ReadKey(true);
 61             }
 62             if (_sw != null)
 63             {
 64                 _sw.Close();
 65             }
 66         }
 67         
 68         static void Fault(int returnCode, string message)
 69         {
 70             Console.WriteLine(message);
 71             if (_sw != null)
 72             {
 73                 _sw.Close();
 74             }
 75             Environment.Exit(returnCode);
 76         }
 77         
 78         static void PrintProcessNames(string[] processNames)
 79         {
 80             foreach (var name in processNames)
 81             {
 82                 Output(string.Format("{0}{1}", name, Environment.NewLine));
 83             }
 84         }
 85         
 86         static void PrintToList(string[] processNames)
 87         {
 88             if (processNames == null || processNames.Length == 0)
 89             {
 90                 return;
 91             }
 92             const string nameTitle = "Name";
 93             const string cpuUsageTitle = "CPU Usage (%)";
 94             var nameColumnMaxLength = Math.Max(processNames.Max(n => n.Length), nameTitle.Length);
 95             var cpuUsageColumnMaxLength = cpuUsageTitle.Length;
 96             var format = string.Format("{{0,-{0}}}  {{1:0.##}}", nameColumnMaxLength);
 97             var head = string.Format(format, nameTitle, cpuUsageTitle).ToUpper();
 98             head += Environment.NewLine + string.Format(format, new string('-', nameColumnMaxLength), new string('-', cpuUsageColumnMaxLength));
 99             var sb = new StringBuilder();
100             while (_times != 0)
101             {
102                 sb.AppendLine(head);
103                 foreach (var name in processNames)
104                 {
105                     try
106                     {
107                         sb.AppendFormat(format, name, GetProcessCpuUsage(name));
108                         sb.AppendLine();
109                     }
110                     catch(Exception)
111                     {
112                     }
113                 }
114                 Output(sb.ToString());
115                 sb.Clear();
116                 if(_times > 0) {
117                     if (--_times == 0) {
118                         break;
119                     }
120                 }
121                 Thread.Sleep(_sleep);
122                 sb.AppendLine();
123             }
124         }
125         
126         static void PrintToTable(string[] processNames)
127         {
128             if (processNames == null || processNames.Length == 0)
129             {
130                 return;
131             }
132             var sb = new StringBuilder();
133             var sb1 = new StringBuilder();
134             foreach (var name in processNames)
135             {
136                 sb.AppendFormat("{0,-6}  ", name);
137                 sb1.AppendFormat("{0}  ", new string('-', Math.Max(name.Length, 6)));
138             }
139             sb.Remove(sb.Length - 2, 2);
140             sb1.Remove(sb1.Length - 2, 2);
141             sb.AppendLine();
142             sb.Append(sb1.ToString());
143             sb.AppendLine();
144             var head = sb.ToString();
145             Output(head);
146             sb1 = null;
147             sb.Clear();
148             while (_times != 0)
149             {
150                 for (int i = 0; i < processNames.Length; i++)
151                 {
152                     var name = processNames[i];
153                     var value = "";
154                     try
155                     {
156                         value = GetProcessCpuUsage(name).ToString("0.00");
157                     }
158                     catch(Exception)
159                     {
160                     }
161                     var length = Math.Max(name.Length, 6);
162                     value = value.PadLeft(length);
163                     if (i + 1 != processNames.Length) {
164                         value = string.Format("{0}  ", value);
165                     }
166                     sb.Append(value);
167                 }
168                 Output(sb.ToString());
169                 sb.Clear();
170                 if(_times > 0) {
171                     if (--_times == 0) {
172                         break;
173                     }
174                 }
175                 Thread.Sleep(_sleep);
176                 sb.AppendLine();
177             }
178         }
179         
180         static void PrintToCsv(string[] processNames)
181         {
182             if (processNames == null || processNames.Length == 0)
183             {
184                 return;
185             }
186             var sb = new StringBuilder();
187             foreach (var name in processNames)
188             {
189                 var tempName = name.Replace(""", """");
190                 if (name.Contains(",") || name.Contains(" ") || name.Contains("""))
191                 {
192                     tempName = string.Format(""{0}"", tempName);
193                 }
194                 sb.AppendFormat("{0},", tempName);
195             }
196             sb.Remove(sb.Length - 1, 1);
197             sb.AppendLine();
198             var head = sb.ToString();
199             Output(head);
200             sb.Clear();
201             while (_times != 0)
202             {
203                 for (int i = 0; i < processNames.Length; i++)
204                 {
205                     var name = processNames[i];
206                     var value = "";
207                     try
208                     {
209                         value = GetProcessCpuUsage(name).ToString("0.00");
210                     }
211                     catch(Exception)
212                     {
213                     }
214                     if (i + 1 != processNames.Length)
215                     {
216                         value = string.Format("{0},", value);
217                     }
218                     sb.Append(value);
219                 }
220                 Output(sb.ToString());
221                 sb.Clear();
222                 if(_times > 0) {
223                     if (--_times == 0) {
224                         break;
225                     }
226                 }
227                 Thread.Sleep(_sleep);
228                 sb.AppendLine();
229             }
230         }
231 
232         static string[] GetProcessNamesAndParseArgs(string[] args)
233         {
234             if (args.Any(n => n.ToLower() == "-v"))
235             {
236                 _printVersion = true;
237             }
238             if (args.Length == 0 || args.Any(n => n.ToLower() == "-h"))
239             {
240                 _printUsage = true;
241                 _printVersion = true;
242                 _pauseWhenFinish = true;
243                 return null;
244             }
245             _pauseWhenFinish = args.Any(n => n.ToLower() == "-p");
246             if (args.Any(n => n.ToLower() == "-l"))
247             {
248                 _listProcessNames = true;
249             }
250             var arg = args.FirstOrDefault(n => n.ToLower().StartsWith("-f:"));
251             if (arg != null) {
252                 _format = arg.Substring(3).ToLower();
253             }
254             arg = args.FirstOrDefault(n => n.ToLower().StartsWith("-s"));
255             if (arg != null) {
256                 int s;
257                 if (int.TryParse(arg.Substring(2), out s)) {
258                     _sleep = s;
259                 }
260             }
261             arg = args.FirstOrDefault(n => n.ToLower().StartsWith("-t"));
262             if (arg != null) {
263                 int t;
264                 if (int.TryParse(arg.Substring(2), out t)) {
265                     _times = t;
266                 }
267             }
268             arg = args.FirstOrDefault(n => n.ToLower().StartsWith("-o:"));
269             if (arg != null) {
270                 var output = arg.Substring(3).ToLower();
271                 try
272                 {
273                     _sw = File.CreateText(output);
274                 }
275                 catch(Exception ex)
276                 {
277                     if (_sw != null)
278                     {
279                         _sw.Close();
280                     }
281                     _sw = null;
282                     Fault(2, string.Format("ERROR: {0}", ex.Message));
283                 }
284             }
285             
286             if (args.Contains("*"))
287             {
288                 return Process.GetProcesses().Select(n => n.ProcessName).OrderBy(n => n).Distinct().ToArray();
289             }
290 
291             var r = args.Where(n => !n.StartsWith("-")).Select(n => GetFriendlyName(n)).ToArray();
292             if (_listProcessNames && r.Length == 0)
293             {
294                 return Process.GetProcesses().Select(n => n.ProcessName).OrderBy(n => n).Distinct().ToArray();
295             }
296             return r;
297         }
298         
299         static void Output(string message)
300         {
301             Console.Write(message);
302             if (_sw == null)
303             {
304                 return;
305             }
306             try
307             {
308                 _sw.Write(message);
309                 _sw.Flush();
310             }
311             catch (Exception)
312             {
313                 _sw.Close();
314                 _sw = null;
315             }
316         }
317         
318         static void PrintUsage()
319         {
320             var n = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
321             var n1 = Path.GetFileNameWithoutExtension(n);
322             Console.Write("Usage:{2}  {0} [-f:<list|table|csv>] [-s<milliseconds>] [-t<times>] [-o:<filename>] [-p] <instance_names|*>{2}  {0} -l [-o:<filename>] [-p] [<instance_names|*>]{2}  -f    output format, default to list.{2}  -s    sleep millisenconds, default to 1000.{2}  -t    times, default to forever.{2}  -p    pause when out of times.{2}  -o    output to file.{2}  -l    print name of processes only.{2}  -h    print help.{2}  -v    print version.{2}{2}Example:{2}  {0} _Total Idle System Svchost {1}{2}  {0} *{2}  {0} * -f:csv -s200 -t10 > 1.csv{2}  {0} -f:csv -s200 -t10 chrome firefox -o:2.csv{2}", n, n1, Environment.NewLine);
323         }
324         
325         static void PrintVersion()
326         {
327             Console.WriteLine(VERSION);
328         }
329         
330         static string GetFriendlyName(string instanceName)
331         {
332             var r = new StringBuilder(instanceName);
333             for(int i=0; i<r.Length; i++)
334             {
335                 var ch = r[i];
336                 if (ch=='(')
337                 {
338                     r[i] = '[';
339                     continue; 
340                 }
341                 if (ch==')')
342                 {
343                     r[i] = ']';
344                     continue;
345                 }
346                 if (ch=='#' || ch=='\' || ch== '/')
347                 {
348                     r[i] = '_';
349                     continue;
350                 }
351             }
352             return r.ToString();
353         }
354 
355         static float GetProcessCpuUsage(string instanceName)
356         {
357             // var total = GetPerformanceCounter("_Total").NextValue();
358             var value = GetPerformanceCounter(instanceName).NextValue();
359             return value / Environment.ProcessorCount;
360         }
361 
362         static PerformanceCounter GetPerformanceCounter(string instanceName)
363         {
364             PerformanceCounter r;
365             if (_caches.TryGetValue(instanceName, out r))
366             {
367                 return r;
368             }
369             r = new PerformanceCounter("Process", "% Processor Time", instanceName);
370             _caches[instanceName] = r;
371             return r;
372         }
373         
374     }
375 }

build.bat

 1 @echo off
 2 pushd "%~dp0"
 3 set csfile=cpuusage.cs
 4 set PATH="C:Program Files (x86)Microsoft Visual Studio2017ProfessionalMSBuild15.0inRoslyn";"C:Program Files (x86)Microsoft Visual Studio2017EnterpriseMSBuild15.0inRoslyn";"C:Program Files (x86)Microsoft Visual Studio2017CommunityMSBuild15.0inRoslyn";"C:Program Files (x86)Microsoft Visual Studio 14.0VCBINamd64";"C:Program Files (x86)Microsoft Visual Studio 14.0VCBIN";C:WINDOWSMicrosoft.NETFramework64v4.0.30319;C:WINDOWSMicrosoft.NETFramework64v3.5;C:WINDOWSMicrosoft.NETFramework64v2.0;%PATH%
 5 csc.exe /target:exe /unsafe+ %csfile%
 6 if ERRORLEVEL 1 (echo ERROR: %ERRORLEVEL%) else (echo Build Success)
 7 echo.
 8 echo Press any key to EXIT...
 9 pause>nul
10 popd

测试:将全部进程10秒中内的CPU使用率导出到CSV,然后查看图表(排除idle和cpuusage)。

C:> cpuusage -t10 -s1000 -f:csv * > 1.csv

原文地址:https://www.cnblogs.com/Bob-wei/p/9267590.html