Using Performance Counters with C# PerformanceCounter Objects

We need to understand reasons behind performance degradation when we experience performance problems with our application. The most important task before we start looking at application performance is to set performance guidelines for our application that we can use to gage and compare against when running performance counters on actual application.PerformanceCounter objects provide us with this information in an object oriented way and storing this information into Windows Registry. Windows has its own Performance Counters and often time you can simply use them instead of creating your own.PerformanceCounter is set to beReadOnly by default, so if we need to write into it, we need to set this property to false.

PerformanceCounter objects have following properties Computer Name, Category Name, Category Instance, Counter Name and several classes that we are going to examine here:

CounterCreationData class holds all the properties needed to create PerformanceCounter object. It has following properties

 

NameDescription
CounterHelp friendly description
CounterName name
CounterType PerformanceCounterType

String DemoCounterName = "DemoCounter";
CounterCreationData DemoData = new CounterCreationData(DemoCounterName, "Training Demo Counter", PerformanceCounterType.SampleCounter );

PerformanceCounterCategory class is design to manage and manipulate PerformanceCounter objects and has following static methods

  • Create - instantiate PerfomanceCounterCategory
  • Delete - deletes PerformanceCounterCategory
  • Exists - checks if PerformanceCounterCategory exist
  • GetCategories - list PerformanceCounterCategories
  • ReadCategory - reads all data associated with a given PeformanceCategory
PerformanceCounterCategory myDemoCategory = new PerformanceCounterCategory("DemoCategory");
if (!PerformanceCounterCategory.Exists("myDemoCategory"))
{
   PerformanceCounterCategory.Create("myDemoCategory", "Training Demo Category", PerformanceCounterCategoryType.SingleInstance, "myDemoCounter", "Training Counter Demo");
}
AND
if (PerformanceCounterCategory.Exists("myDemoCounter"))
{
   PerformanceCounterCategory[] DemoCategories = PerformanceCounterCategory.GetCategories("mymachinename");
   foreach (PerformanceCounterCategory ThisCategory in DemoCategories)
   {
     Console.WriteLine(ThisCategory.CategoryName);
   }
}

PerformanceCounter class provide information about processes and we can for example get a list of processes for ASP.NET
StringBuilder myStringBuilder = new StringBuilder();
myStringBuilder.Append("Counter Name:" + myDemoCounter.CounterName + "\r\n");
myStringBuilder.Append("Counter Type:" + myDemoCounter.CounterType.ToString() + "\r\n");
myStringBuilder.Append("Category Name:" + myDemoCounter.CategoryName + "\r\n");
myStringBuilder.Append("Instance Name:" + myDemoCounter.InstanceName + "\r\n");
myStringBuilder.Append("Machine Name:" + myDemoCounter.MachineName + "\r\n");
MessageBox.Show(myStringBuilder.ToString());

StackTrace class allows you to examine .NET runtime's call stack. Every time we call method we add StackFrame into the stack. Every time we get runtime Exception its StackTrace property is set to current StackTrace.
try
{
  Int32 x = 1;
  x--;
  Int32 i = 20 / x;
}
catch (DivideByZeroException Problem)
{
  Debug.Assert(false, Problem.StackTrace);
}