The Scenario library is used to instrument your applications to measure and report the execution time and CPU usage associated with specific application scenarios. The Scenario measurements are useful in performance engineering during all stages of application development, including Test and deployment. With Scenario markers, every time an application scenario executes, you are able to obtain these measurements of execution time and CPU utilization. These measurements are reported in ETW events. . Once your application is instrumented, you can gather these execution time measurements by enabling an ETW Listener like the MeasurementWare Web App Trace Explorer to gather Scenario trace events.
The Scenario instrumentation library is very simple to use. You need to add calls to the Scenario object to an existing application marking the beginning and end of each scenario in order to instrument it. In new application development projects, you should add Scenarios calls to instrument the application at the outset of development and unit testing. Using the Scenario instrumentation library, every unit test of your application scenario can also serve as a performance timing test.
The Scenario instrumentation library was originally published on an open source Microsoft site named CodeGallery, but is now mainly available here. Special thanks to Jonathan Hardwick, PhD, currently a Computer Science instructor at the University of Central Minnesota, who was responsible for publishing that version of the code.
Windows performance counters are useful at a high level, but lack the detail that is usually required at the application-level. Visibility at the application level requires instrumenting your apps, and the Scenario library was specifically developed to make that easy to do. An earlier version of the Scenario class library known as the MeasurementBlock ships as Microsoft.VisualStudio.Diagnostics.Measurement.dll, which is installed at C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE. Both the Scenario library and the MeasurementBlock contain methods that are used to mark the beginning (Scenario.Begin) and end of an application-level scenario (Scenario.End). Using either library, a call to the End() method will generate an ETW event that contains the application-level timing data we are interested in.
To get started, download the Scenario instrumentation library: Download
Installation and usage notes
Unpack the Scenario.zip file and save the files in a convenient place on your computer. The distribution library contains a Native version of the Scenario class and a Scenario.h header file to include in your native C++ project.
For .NET applications, there are separate versions of the Scenario class library that are built for version 3.5 and version 4.0 of the .NET Framework, respectfully. The following instructions refer to using the .NET Framework version of the Scenario instrumentation library with your managed code applications, including ASP.NET web applications.
To start using the Scenario library, in Visual Studio Add a Reference to the appropriate version of the Scenario.Managed.dll to your Project. The Scenario library contains two public classes. You use the Scenario class to mark the beginning and end of an application scenario you wish to instrument. The Scenario class internally calls an ExtendedStopwatch class, which extends the standard .NET Stopwatch class by adding CPU time measurements using calls to the Windows QueryThreadCycleTime function.
To instrument an application scenario,
- instantiate a new Scenario object prior to the scenario being executed.
- Just before the scenario begins execution, call the Begin() method on the Scenario object.
- When the scenario completes, call the Scenario object’s End() method.
as in the following code snippet:
Scenario.Scenario scenario = new Scenario(); scenario.Begin(); ... scenario.End();
Frequently, the application scenario timing data alone is not enough to understand why a scenario is taking too long execute. You may need to provide additional attributes to further characterize the scenario. The Scenario class exposes two Properties to enable you to characterize key run-time aspects of the scenario being executed:
- a Category string, and
- a numeric Size field.
These Properties can be set when the Begin() or End() methods are called, and they can also be specified when you first instantiate a new Scenario object using the new operator. For instance, it is often helpful to understand the number or rows returned when SELECT statement is executed in an application scenario that performs a database Query. Since the number or rows returned when the SELECT statement executes is not known until after the Query runs, you can wait to set the Size Property for the Scenario Object that measures the execution time of the database Query using that Object’s End(size) Method call.
For example, to instrument an application scenario with an inner loop, you would code:
Scenario.Scenario outerScenario = new Scenario.Scenario(nrChartSeries, "Function=DailyChartOuterLoop;template=" + chartDefinition.Template.ChartName); outerScenario.Begin();
which sets the Scenario object Size Property to the number of inner loop iterations and encodes the Category string with a series of Key=Value pairs separated by semicolons (‘;’).
Since the Scenario class also supports nesting Scenario objects, another Scenario object that is created to instrument the inner processing loop can reference a parent Scenario:
Scenario.Scenario innerScenario = new Scenario.Scenario(1, "Function=DailyChartOuterLoop;SubFunction=InnerLoop;series=" + chartseries.CounterName, outerScenario); innerScenario.Begin();