The CLRProfiler for the .Net Compact Framework, Part V: Controlling the profiler programmatically

If you've used the CLRProfiler for NetCF you've probably noticed that your application runs much slower when being profiled. You likely have also seen the huge amount of data the profiler generates, even for relatively simple applications. The time it takes the profiler to run coupled with the volume of data it creates can sometimes make the profiler impractical to use. For example, I've had customers tell me that it can take several minutes to start an application while profiling. If it takes you several more minutes just to navigate to the portion of the application you'd like to profile, it can quickly become extremely frustrating.

The CLRProfiler ships with an additional assembly you can reference and call from your application to control the profiler while your application is running. This assembly, called NetCFCLRProfilerControl contains APIs you can use to start and stop profiling, insert comments into the profiling log, dump the contents of the GC heap on demand, and so on. The ability to control when the profiler collects data enables you to profile only the sections of your application you want to, rather than having the profiler collect data all the time. In this way, your application will start faster and there will be less data to sift through later.

In this post I'll describe how to use the APIs provided by the NetCFCLRProfilerControl.

Using the NetCFCLRProfilerControl Assembly

The following steps are required to use NetCFCLRProfilerControl from your application:

  1. Reference NetCFCLRProfilerControl in your Visual Studio project.
  2. Add code to your application to call the APIs.
  3. Deploy NetCFCLRProfilerControl along with your application.
  4. Start your application using the CLRProfiler.

Referencing NetCFCLRProfilerControl

NetCFCLRProfilerControl is installed on the desktop machine in same directory as the NetCFCLRProfiler executable. On my machine the files are in C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\bin. 

You'll need to add a reference from your application to NetCFCLRProfilerControl to use its APIs. If you're using Visual Studio you can add this reference using the standard "Add Reference..." dialog.   

Public APIs

NetCFCLRProfilerControl contains one public class called CLRProfilerControl which contains the following public static members:

Member Notes

bool ProcessIsUnderProfiler { get; }

Returns true if your application was launched using the CLRProfiler. Note that this is independent of whether the profiler is actually logging allocations or calls at the time.

bool AllocationLoggingActive { set; get; }

A boolean property that controls whether the profiler logs managed allocations.

bool CallLoggingActive { set; get; }

A boolean property that controls whether the profiler logs method calls.

void LogWriteLine(string comment)

void LogWriteLine(string format, params object[] args)

Enables you to insert comments into the profiling log. These comments show up in the various profiler views to help you narrow down exactly where in your application certain allocations or calls were made. See the example later in this post.

void DumpHeap()

Causes the profiler to display a graphical view of the GC heap. Individual views will also show up on the profiler's summary form when the application exits.

 

Deploying your application

NetCFCLRProfilerControl is not installed on the device automatically. You'll need to deploy it along with your application. It's probably easiest to deploy NetCFCLRProfilerControl to the same directory as your application but you can also install it in the GAC if you prefer.

Launching your application

The APIs provided by NetCFCLRProfilerControl have no effect if your application isn't started using the CLRProfiler. However, assuming you are going to use the APIs to control when the profiler logs allocations and/or calls, be sure to clear the relevant checkboxes on the profiler's main form before launching your application (otherwise you'll be logging all the stuff you wanted to prevent in the first place!).

 

After clearing the checkboxes, start your application using the profiler as you always have. The actions of the profiler will now be controlled by your application instead of the CLRProfiler's user interface.

Turning profiling on and off

Assuming you've started your application with the "Profile" checkboxes on the profiler's main form cleared, no logging of allocations or calls will occur. You can turn profiling on using the AllocationLoggingActive and CallLoggingActive properties.

The following example turns allocation logging on just before entering a loop, then turns logging back off when the loop completes:

private void btnCheckOut_Click(object sender, EventArgs e)
{
CLRProfilerControl.AllocationLoggingActive = true;
for (int i = 0; i < 20; i++)
{
m_cart.ProcessCart();
}
CLRProfilerControl.AllocationLoggingActive = false;
}

Inserting comments into the profiling log

The ability to insert comments into the profiling log is a cool feature that enables you to place your own visual markers into some of the profiler's graphical views. 

Here's an example that inserts comments denoting the beginning and end of the execution of a loop:

private void btnCheckOut_Click(object sender, EventArgs e)
{
CLRProfilerControl.LogWriteLine("Before ProcessCart loop");
for (int i = 0; i < 20; i++)
{
m_cart.ProcessCart();
}
CLRProfilerControl.LogWriteLine("After ProcessCart loop");
}

After the application exits, your comments show up in several places in the CLRProfiler UI. First, the summary screen includes a button that brings up a window giving the timestamp of each comment. You can use this as a rudimentary timing mechanism in your application:

The comments also show up in various views throughout the UI For example, in the Timeline View, the comments show up as vertical green lines that indicate the time at which the comment was logged. You can see the text of a given comment by hovering the house over its green line. This allows you to see the state of the GC heap between different points of interest as your application ran.

Dumping the GC Heap

The final feature available via NetCFCLRProfilerControl is the ability to take a snapshot of the GC heap on demand. The DumpHeap method causes a heap view to be displayed immediately. You can also access all the heap views taken while the app ran from the Summary View after the application exits.

 

Thanks,

Steven

This posting is provided "AS IS" with no warranties, and confers no rights.