only for RuBoard |
Tucked away in the Administrative Tools folder within the Control Panel is the infamous Windows Performance Monitor. For years , network administrators have used this tool (shown in Figure 6-2) to profile everything from network traffic, SQL Server performance, memory, threads, and the cache. It is a very useful tool made even better by several additional counters provided by .NET.
These supplementary counters allow you to profile low-level processes such as CLR memory allocation and the JIT compiler. In addition, ASP.NET provides several useful counters for keeping an eye on sessions, requests , and the cache.
ASP.NET also provides a counter for monitoring exceptions thrown by the CLR. You can add it to the performance monitor by right-clicking on the performance graph and selecting "Add Counters" from the context menu. This step will bring you the dialog shown in Figure 6-3.
Then in the Performance object drop-down listbox, select ".NET CLR Exceptions." This category contains several counters, including "# of Exceps Thrown." There are several instances of this counter: _Global_ , zero or more devenv counters, and mmc .
In the System.Diagnostics namespace, classes allow you to access any performance counter. Example 6-12 shows how to read values from a performance counter. Also shown is the " # of Exceps Thrown" counter, which tells you how many exceptions were thrown since the CLR was started.
Imports System Imports System.Diagnostics Friend Class Test Public Shared Sub Main( ) If PerformanceCounterCategory.Exists(".NET CLR Exceptions") Then Dim pc As New PerformanceCounter(".NET CLR Exceptions", _ "# of Exceps Thrown", "_Global_", True) Console.WriteLine(pc.RawValue( ).ToString( )) End If End Sub End Class
The code first checks for the existence of the performance counter category by calling the shared method PerformanceCounterCategory.Exists . If it is found, an instance of PerformanceCounter is created by using the performance category, the counter name, and the instance name . These values can be readily obtained by looking in the Add Counters dialog from Figure 6-3. Finally the value is written to the console. It's not the greatest example, but the performance data is there, and you can access it.
What does the number of exceptions thrown by the CLR tell you as a software developer? Well, not much. It would probably be more useful to monitor the number of exceptions thrown in your own application versus the entire runtime. Luckily, as Example 6-13 demonstrates , the .NET Framework provides ample support for creating custom profiling counters.
Imports System Imports System.Diagnostics Friend Class Test Public Shared Sub Main( ) If Not PerformanceCounterCategory.Exists("My Apps") Then 'Create your performance counters Dim perfCounters As CounterCreationDataCollection _ = New CounterCreationDataCollection( ) 'Create exception performance counters Dim exceptionCounter As CounterCreationData = _ New CounterCreationData( _ "Exceptions Thrown", _ "This counter tracks the " & _ "total number of exceptions thrown " & _ "by all of my applications.", _ PerformanceCounterType.NumberOfItems32) 'Add counter perfCounters.Add(exceptionCounter) 'Create another counter to show executions Dim runCounter As CounterCreationData = _ New CounterCreationData( _ "Run Count", _ "This counter profiles the " & _ "total number of times " & _ "my applications have run on this machine.", _ PerformanceCounterType.NumberOfItems32) 'Add second counter perfCounters.Add(runCounter) 'Add counters to Performance Monitor PerformanceCounterCategory.Create("My Apps", _ "My Counters Help", _ perfCounters) End If End Sub End Class
As in Example 6-12, the existence of the performance category is checked. In this example, the category is called " My Apps ." If the category does not exist, it is created. Each performance category can contain any number of counters. In the example, one counter is created to track exceptions and another is created to track the number of times an application is run. Each counter is an instance of System.Diagnostics.CounterCreationData .
When creating the counter, the name of the counter, its help text, and its data type are provided. The help text is included for the benefit of the Add Counters dialog. A message box displays this text when the Explain button is pressed, as shown in Figure 6-4.
The important thing to remember is that counters cannot be added once the performance category is created, so think before jumping in head first.
After the counter is created, it is added to a collection of type CounterCreationDataCollection , which ends up as the third parameter to the PerformanceCounterCategory.Create method. The first two parameters are the name of and the help text for the category. This method makes the category and counters available to the Performance utility. If you want to track exceptions, you could place code similar to Example 6-13 into the startup routines of your application. If the category does not exist and you try to access it, an exception will be thrown. The irony!
|
Now that a performance category exists, you need a way to write to the counter. If you were looking for an excuse to create your own exception object, here it is. Example 6-14 contains a derived exception class that writes to the exception counter that was just discussed.
Public Class MyBaseException : Inherits ApplicationException Public Sub New( ) If PerformanceCounterCategory.Exists("My Apps") Then Dim pc As New PerformanceCounter("My Apps", _ "Exceptions Thrown", False) 'Increment the counter pc.Increment( ) End If End Sub End Class
In this instance, the constructor of the PerformanceCounter class takes the category name, the counter name, and whether or not the counter is read-only. Of course, to access the counter for a write operation, this last parameter must be False . Here, the Increment method adds one to the current counter value. To test the entire process, use code like this:
Try Throw New MyBaseException( ) Catch e As MyBaseException If PerformanceCounterCategory.Exists("My Apps") Then Dim pc As New PerformanceCounter("My Apps", _ "Exceptions Thrown") 'Increment the counter Console.WriteLine(pc.RawValue( ).ToString( )) End If End Try
As an exercise, you might consider adding the ExceptionInfo class or the functionality it provides to your performance tracking exception class.
only for RuBoard |