System.Diagnostics.PerformanceCounter and % Processor Time on multi-core or multi-cpu

While trying to build a task-manager type tool, I noticed that the idle task on my machine sometime consumed over 100% of the CPU!  160%, even 180%.  What's going on?  I asked the base-class framework team and they've clued me in:

Process and Processor have different aggregation types.

· “\Process(…)\% Processor Time” can go up to N*100 (where N is the number of CPUs) because it adds up the CPU usage of the requested process across all the CPUs.

· “\Process(_Total)\% Processor Time” should always be around N*100 (where N is the number CPUs) because it adds up the CPU usage of each process, including the idle process.

· “\Processor(…)\% Processor Time” can go up to 100 because it’s the CPU usage of the requested CPU.

· “\Processor(_Total)\% Processor Time” can go up to 100 because it’s the average CPU usage across all CPUs.

In the above, Process(...) indicates a particular instance of the perf counter, pertaining to a particular process on the machine. If you have a dual-core machine or a multi-cpu machine - these days even basic laptops have Core Duos - then you will see this behavior.

Note: this assumes your code uses NextValue(), not NextSample. Something like this:

1 public class MyProcessInfo : INotifyPropertyChanged, IDisposable

2 {

3 System.Diagnostics.Process _p;

4 System.Diagnostics.PerformanceCounter _perfCounter;

5 public MyProcessInfo(System.Diagnostics.Process p)

6 {

7 _p = p;

8 _Id = p.Id;

9 _WorkingSetInKbytes = p.WorkingSet64 / 1024;

10 _perfCounter =

11 new System.Diagnostics.PerformanceCounter("Process",

12 "% Processor Time",

13 p.ProcessName,

14 true);

15 _perfCounter.NextValue();

16 }

17

18 public void UpdateUtilization()

19 {

20 CpuUtilization = (int)(_perfCounter.NextValue());

21 }

Keep in mind that you need to delay "about 1 second" between calls to NextValue(), as per the documentation!