ServicesResourcesConferencesOur TeamWeblogsAboutContact
   
Getting the Current Process' (your own!) CPU usage

I'm currently living in performance-testing land for a distributed application. This time, it's not enough to merely know the time it takes to execute certain functionality, but I also need to know which toll a certain feature has on all machines involved (client, server, DB server).

I've therefore created another small helper class which can be used to report the exact CPU usage ("% Processor Time" in perfmon.exe) between two points in time for your process.

Usage

static void Main(string[] args)
{
   CPUMeter mtr = new CPUMeter();

   // do some heavy stuff
   double result = 0;
   for (int i = 0;i<100000000; i++)
   {
      result = result+Math.Sin(i);
   }

   double usage = mtr.GetCpuUtilization();

   Console.WriteLine("Done. CPU Usage {0:#00.00} %", usage);
   Console.ReadLine();
}

Source

using System.Diagnostics;

public class CPUMeter: IDisposable
{
   CounterSample _startSample;
   PerformanceCounter _cnt;

   /// Creates a per-process CPU meter instance tied to the current process.
   public CPUMeter()
   {
      String instancename = GetCurrentProcessInstanceName();
      _cnt = new PerformanceCounter("Process","% Processor Time", instancename, true);
      ResetCounter();
   }

   /// Creates a per-process CPU meter instance tied to a specific process.
   public CPUMeter(int pid)
   {
      String instancename = GetProcessInstanceName(pid);
      _cnt = new PerformanceCounter("Process","% Processor Time", instancename, true);
      ResetCounter();
   }

   /// Resets the internal counter. All subsequent calls to GetCpuUtilization() will 
   /// be relative to the point in time when you called ResetCounter(). This 
   /// method can be call as often as necessary to get a new baseline for 
   /// CPU utilization measurements.
   public void ResetCounter()
   {
      _startSample = _cnt.NextSample();
   }

   /// Returns this process's CPU utilization since the last call to ResetCounter().
   public double GetCpuUtilization()
   {
      CounterSample curr = _cnt.NextSample();

      double diffValue = curr.RawValue - _startSample.RawValue;
      double diffTimestamp = curr.TimeStamp100nSec - _startSample.TimeStamp100nSec;

      double usage = (diffValue / diffTimestamp) * 100;
      return usage;
   }

   private static string GetCurrentProcessInstanceName()
   {
      Process proc = Process.GetCurrentProcess();
      int pid = proc.Id;
      return GetProcessInstanceName(pid);
   }

   private static string GetProcessInstanceName(int pid)
   {
      PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");

      string[] instances = cat.GetInstanceNames();
      foreach (string instance in instances)
      {
         
         using (PerformanceCounter cnt = new PerformanceCounter("Process",  
              "ID Process", instance, true))
         {
            int val = (int) cnt.RawValue;
            if (val == pid)
            {
               return instance;
            }
         }
      }
      throw new Exception("Could not find performance counter " + 
          "instance name for current process. This is truly strange ...");
   }

   public void Dispose()
   {
      if (_cnt!=null) _cnt.Dispose();
   }
}

Have fun!

posted on Tuesday, June 22, 2004 9:37 PM

# re: Getting the Current Process' (your own!) CPU usage @ Tuesday, July 10, 2007 5:27 AM

Thanks Ingo, just what I needed!

By the way, do you know how to do the same thing for selecting the "current" instance of the ASP.NET counters? E.g. I'd like to record "ASP.NET Applications" "Requests Executing" for the current .NET application, but I'm not sure how to find the right instance name for the current application. I'm hoping you might know :-)


John Rusk


Powered by Community Server, by Telligent Systems