Reading and Publishing Performance Counters in .NET
Windows uses performance counters to collect and present performance data from running processes. Windows itself provides hundreds of performance counters, each monitoring a specific aspect of your system, from CPU utilization to network traffic. In addition, other applications such as SQL Server or Exchange publish their own custom performance counters that integrate into the Windows performance monitoring system.
Performance counters are grouped into categories such as Memory, Processor and PhysicalDisk. Each category contains one or more performance counters. For example, the Memory category includes such categories as Available Bytes, Cache Bytes, and Committed Bytes. Some categories also support an intermediate level of organization called an instance. For example, the Network Interface category has one instance for each network interface in your computer. You can thus decide which network card to monitor with this instance.
Windows provides the System Monitor application (shown in Figure 1) to let
you see performance counters in action. But if you're working in .NET, you can
go much deeper than this by using the
System.Diagnostics.PerformanceCounter class. In
this article, I'll show you how to monitor existing performance counters and how
to create your own performance counters.
Reading Performance Data
Visual Studio .NET makes it supremely easy to read existing performance counters in your application, thanks to Server Explorer. If you haven't discovered Server Explorer yet, it's normally docked as a slide-out window on the left hand side of the VS .NET workspace. When you slide it out, you'll find a treeview that lets you drill into all sorts of resources, as shown in Figure 2. As you can see, Performance Counters are one of the categories of resource that you can find here.
In this screenshot, Skyrocket is the name of my local computer, .NET CLR
Security is a performance counter category, Total Runtime Checks is a
performance counter, and _Global_ is a performance counter instance. You can
drag and drop a performance counter instance from Server Explorer to a .NET
Windows form. When you do this, Visual Studio .NET creates a performance counter
component on the form. This is a visual wrapper for an instance of the
For a quick demonstration, I dragged a performance counter and a timer control to a form, added some buttons and a listbox, and wrote a tiny bit of code:
Private Sub btnShowCPU_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnShowCPU.Click ' Toggle the state of the CPU performance ' counter display in the list box If btnShowCPU.Text = "Show CPU usage" Then btnShowCPU.Text = "Stop" Timer1.Enabled = True Else btnShowCPU.Text = "Show CPU usage" Timer1.Enabled = False End If End Sub Private Sub Timer1_Tick(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Timer1.Tick ' Display a new performance counter value ' in the list box lbPerfData.Items.Add("CPU usage: " & pcCpuTime.NextValue() & "%") End Sub
Figure 3 shows this form in action, collecting samples of CPU usage. As you
can see in the code, the samples are generated by calling the
NextValue() method of a
Looking into the code that the Windows Forms Designer generated shows how
easy it is to set up a
PerformanceCounter for an existing
Friend WithEvents pcCpuTime As System.Diagnostics.PerformanceCounter Me.pcCpuTime.CategoryName = "Processor" Me.pcCpuTime.CounterName = "% Processor Time" Me.pcCpuTime.InstanceName = "_Total" Me.pcCpuTime.MachineName = "skyrocket"
After you set the
MachineName properties, you can read
a sample of the performance counter any time that you like. The
NextValue method will return the system's calculated value for the
performance counter. There's also a
NextSample method which returns
a point-in-time sample; this may differ from the calculated value for counters
which require multiple samples (for example, those that return a bytes per