1. Introduction to Performance Counter & Monitor
Perfmon is a windows tool, and it is useful to monitor ‘System’ and ‘Application Performance’ by measuring various parameters and plotting it as a graph. The measuring parameter is called ‘Performance Counter’. In this example, we will add our own Performance Counter that tracks the UI activity of our sample application. Before that, we should first know what is ‘PerfMon’ tool and how it uses the Performance Counters to track and plot system or application performance. Have a look at the below screenshot:
The perfmon is a tracking tool which monitors the Performance Counters. The above screenshot shows the Perfmon tool. Here, the toolbar icons marked above are useful to add or remove a Performance Counter. Once we add a Counter, it will be shown in the tool’s bottom. In our example, ‘% Processor Time’ is added as a Counter which is marked in the above screenshot. Once the Counter is added, the Perfmon tool plots the graph taking the Time Unit as X-Axis and ‘% CPU Usage’ as the Y-axis. The below video shows how to plot ‘Private byte’ as a Counter to track the memory taken up by a process:
Video 1: Using Windows PerfMon utility
Now let us try creating our own Performance Counter, which tracks three button clicks of of our example. Note, you can imagine how to apply this study based on your application work nature. For example, if you have written a billing App for a grocery store, you can monitor the speed of the billing counters by tracking how many products billed over a period by a billing counter staff.
2. C# Objects Needed For Performance Counter Creation
The below picture shows some very important C# Objects involved in application performance monitoring. They together help in creating an application specific Custom Performance Counters. Have a look at the below picture:
2.1 Performance Counter Category
The Category groups the Performance Counters logically. For example, in the past video, we saw the Counters groups named Process and System. These groups help in the picking the Performance Counter in a quick way.
2.2 Counter Creation Data
The Counter Creation Data points out the Performance Counter Type (Simple counts, Time Measure, Average etc.,), Counter Name and Descriptive Text so that the monitor tool will pass on that knowledge to the user stating what the Performance Counter will do for them. The name that we will give here will be used while creating actual Performance Counter objects.
2.3 Performance Counters
The Performance Counter is the object which has the functions like Increment, decrement, time Elapsed, etc. These counters take the data needed for creating it from ‘Counter Creation Data’ C# Object.
To set up a custom Performance Counters, we create the ‘CounterCreationData’ object. Because constructing the Performance Counters needs this creation data. These Counter Creation Data are added to a collection and given to the ‘Category Group’. We get more insight into it while we start our coding. For now, let us look at the sample application that we will create in this article.
3. About This Performance Counter Example
The Screenshot of the Example application is shown below:
The Register and Leave button share same Performance Counter called Register Click and Update button uses a one more Counter called Update Click. This example form increments the Counters Register Click and Update Click when user clicks the relevant buttons Register and Update. The Leave button will reduce the Register Click performance count by one. This example looks hollow. But it is just for a tryout purpose.
In the real case, these kinds of click counts are useful to measure Performance of the Operator. Say, for example, a click count on the print button measures how many billing is done in an hour by an operator on the billing counter of a retail shop. The perfmon can plot the graph over time, showing how many billing a billing counter staff clears. You can think of a better example than this one once you know how this Example works.
4. Creating Performance Counter in C# – Code Explanation
In this section, we will implement the C# Form-Behind code to create and use Custom Performance Counters.
4.1 Namespace Required
First, we add the required namespace to the implementation file. The code is below:
1 2 |
//Sample 01: Using Directive using System.Diagnostics; |
4.2 Category Group Name
We declare a string variable to specify the Category Group Name for our Counters. While using the PerfMon tool we can easily find our counters under the category group called Button Usage.
1 2 |
//Sample 02: Category Name and Counters belongs to it private string CategoryName = "Button Usage"; |
4.3 Counter Object Declarations
Dotnet framework packs the
PerformanceCounter
class in
System.Diagnostics
namespace. With this object we can read data from the pre-set counters of the OS or read/write data if it is a custom counter. We declare two
PerformanceCounter
variables to hold the reference to the Performance Counter objects. We will use these objects to count the button clicks. Below is the code:
1 2 3 |
//Sample 03: Click counter for buttons private PerformanceCounter RegisterClicks; private PerformanceCounter UpdateClicks; |
4.4 Check Category Already Present
The class
PerformanceCounterCategory
is useful for creating the Category Groups of the Performance Counters. Using the same class, we are making a call to the static function
Exists()
in the form load to check the Category Name Button Usage is already existing.
1 2 3 4 5 |
//Sample 03: Create Counters for Button Clicks private void frmCounterEx_Load(object sender, EventArgs e) { //3.1: Check counter available bool Counter_Available = PerformanceCounterCategory.Exists(CategoryName); |
4.5 CounterCreationData for RegisterClick & UpdateClick
Once we make sure the Category does not exist, we create our custom Counters. First, the
CounterCreationData
objects are created by pointing out the
CounteName
,
CounterType
, and
CounterHelp
properties. In our case, we are making the counter that counts the button clicks by the Operator of the application. So, we use
NumberOfItems32
as the counter type from the enum
PerformanceCounterType
. The help string which we set via
CounterHelp
will show up in the perfmon tool. We will see that while we run this example and verify the result. Below is the code which sets needed properties of the
CounterCreationData
object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if (!Counter_Available) { //3.2: Form Countercreation Data CounterCreationData RegButtonClick = new CounterCreationData(); RegButtonClick.CounterName = "ResgisterClick"; RegButtonClick.CounterType = PerformanceCounterType.NumberOfItems32; RegButtonClick.CounterHelp = "How many time register button is " + "clicked. Useful to know how many customers registered for " + "a given time"; CounterCreationData LeaveButtonClick = new CounterCreationData(); LeaveButtonClick.CounterName = "UpdateClick"; LeaveButtonClick.CounterType = PerformanceCounterType.NumberOfItems32; LeaveButtonClick.CounterHelp = "How many time Leave button " + "is clicked. Useful to know how many customers left " + "for a given time"; |
4.6 Add Counters to CounterCreationDataCollection
Once
CounterCreationData
is ready, we add it to the collection
CounterCreationDataCollection
by using the
add
method. Note that we will use RegisterClick counter for both Register and Leave button clicks. Below is the code change:
1 2 3 4 |
//3.3: Create Collection of CreationData CounterCreationDataCollection ClickCounters = new CounterCreationDataCollection(); ClickCounters.Add(RegButtonClick); ClickCounters.Add(LeaveButtonClick); |
4.7 Create Counter Category
Next, we are making a call to
Create
static method of the
PerformanceCounterCategory
to create the category group called ‘Button Usage’. We pass the ClickCounters collection set up in the past step to create a new counter type. Also, note that before making a call to this function we are already checked the counter not exist. As we make this new Performance Counter category in the form load event, the counter will be visible on the Performance Counter only after loading the form at-least one time in memory. This Create call may fail stating that “Requested registry access is not allowed” as we are making a change at the OS level (i.e.) adding a new performance category type and two new counters inside it. So, we need to run this sample EXE or Visual Studio (If you like to launch it from Visual studio) in admin mode.
1 2 3 4 5 |
//3.3: Create Collection of CreationData CounterCreationDataCollection ClickCounters = new CounterCreationDataCollection(); ClickCounters.Add(RegButtonClick); ClickCounters.Add(LeaveButtonClick); |
4.8 Create Performance Counters
OK. Everything is ready. Now we will create our own Performance counters. We can create the custom counters using the constructor for the class
PerformanceCounter
. The first parameter is a category name which we supply from our form-level variable. Next, we pass the Performance Counter name to this constructor. Note, here we are giving the same name which we registered with the
CounterCreationData
. The code is below:
1 2 3 |
//3.5: Now create actual measuring counters RegisterClicks = new PerformanceCounter(CategoryName, "ResgisterClick", false); UpdateClicks = new PerformanceCounter(CategoryName, "UpdateClick", false); |
4.9 Track Button Clicks Via Performance Counters
At this stage, windows know new custom counters known as RegisterClick and UpdateClick under the category name Button Usage. Now we will write code to do actual counting of the button clicks. In the button click events, we are making the counts. Register and Leave buttons share same counter object called RegisterClicks. In the register button click, we raise the counter by one. The same way in the leave button click, we reduce the same counter by one. We do that by making a call to the API functions
Increment()
and
Decrement()
. Update click uses separate counter called UpdateClick. Below is the code which uses our custom counters:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//Sample 04: Increment and Decrement Counters private void btnRegister_Click(object sender, EventArgs e) { RegisterClicks.Increment(); } private void btnLeave_Click(object sender, EventArgs e) { RegisterClicks.Decrement(); } private void btnUpdate_Click(object sender, EventArgs e) { UpdateClicks.Increment(); } |
4.10 Deleting the Counters
Finally, we delete our custom counters in the
form closing event
. So, to see performance counters in Perfmon tool, our example should be in running state. Since this is just a demo, we delete these counters while closing the form. In real-world, the counter exists between user sessions. The code is below:
1 2 3 4 5 6 7 |
//Sample 05: If counter category Exists, delete it private void frmCounterEx_FormClosed(object sender, FormClosedEventArgs e) { bool Counter_Available = PerformanceCounterCategory.Exists(CategoryName); if (Counter_Available) PerformanceCounterCategory.Delete(CategoryName); } |
5. Running Our Example
To see how our own Performance counters work, launch the sample EXE. You can also start visual studio (If we plan to run the application from visual studio IDE Itself) in administrator mode and run the project. After opening the form, you can launch performance monitor by using the PerfMon. The Performance monitor tool will now display our performance counters under the group Button Usage. Add all our custom counters to track and then click the buttons on the form to see the change in the graph plotted over time. The below video shows our custom counters in action.
Video 2: Custom Performance Counters
Source Code: Download Custom Performance Counter Example From Google Drive
Categories: C#
Tags: CounterCreationData, CounterCreationDataCollection, Decrement(), Increment(), perfmon, PerformanceCounter, PerformanceCounterCategory