You want to find the source of a problem that appears to be associated with a particular page of your application, such as a page that completes its operations more slowly than desired.
Enable page-level tracing for the page in question by
setting the Trace
attribute of the @
Page
directive in the .aspx
file to
"true
" and then using
Trace.Write
(or Trace.Warn
)
statements as warranted in your code-behind to write trace
information to the trace output.
Example 10-1 through Example 10-3 show the code we’ve written
to illustrate this solution. Example 10-1 shows the
.aspx
file for a typical ASP.NET page. The
code-behind class for the page appears in Example 10-2 (VB) and Example 10-3 (C#). By
running the page and analyzing the trace sequence, you can see how
long certain key operations are taking. The output with the trace
sequence is shown in Figure 10-1.
Tracing tracks and presents
the execution details about an HTTP request. The
TraceContext
class is actually where ASP.NET
stores information about an HTTP request and its trace information.
You access the TraceContext
class through the
Page.Trace
property of an ASP.NET page. To enable
tracing for the page, be sure to set the Trace
attribute of the @
Page
directive in the .aspx
file to
"true
“, as shown in Example 10-1.
The TraceContext
class has
two methods for writing
statements into the trace log: Write
and
Warn
. The only difference is that
Warn
outputs statements in red so that they are
easier to spot in the trace log. Both methods are overloaded and have
three versions. If you pass a single string argument, ASP.NET writes
it to the Message column of the trace log, as shown in Figure 10-1. If you use two string arguments, the first
string appears in the Category column and the second in the Message
column. If you use a third argument, it must be of type Exception and
contain information about an error, which ASP.NET then writes to the
trace log.
If you’ve placed Trace.Write
or
Trace.Warn
statements in your code, you
don’t have to worry about removing them later. The
common
language runtime (CLR) will ignore them
when tracing is disabled. Just be sure to disable page-level tracing
before deploying your application to a production environment.
In our example, Trace.Write
is used three times to
put custom messages into the trace sequence: the first time to mark
the start of the concatenations and the second to mark the end of the
concatenations. The third message outputs the average time for a
string concatenation. The latter shows how inefficient it is to use a
classic concatenation operator (&
or
+
) in ASP.NET string operations. (See Recipe 16.2 for more discussion of this code as well as
the advantages of using the StringBuilder
object
to build strings over the classic concatenation operators.)
Notice in Figure 10-1 that the trace log (beginning
with “Request Details”) appears
below the standard output for the ASP.NET page that is enabled for
Trace
. Here’s an explanation of
the “Trace Information” section
contents in the trace log:
A custom trace category that you
specified as the first argument in a
Trace.Write
(or Trace.Warn
)
method call.
A custom trace message that you specified as the second argument in a
Trace.Write
(or Trace.Warn
)
method call.
The time, in seconds, since the request processing was started (a running total).
The time, in seconds, since the last message was displayed. This column is especially helpful for seeing how long individual operations are taking.
Example 10-1. Page-level tracing (.aspx)
<%@ Page Trace="True"
Language="vb" AutoEventWireup="false"
Codebehind="CH10TestPageLevelTracingVB.aspx.vb"
Inherits="ASPNetCookbook.VBExamples.CH10TestPageLevelTracingVB"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test Page Level Tracing</title>
<link rel="stylesheet" href="css/ASPNetCookbook.css">
</head>
<body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0">
<form id="frmTracing" method="post" runat="server">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td align="center">
<img src="images/ASPNETCookbookHeading_blue.gif">
</td>
</tr>
<tr>
<td class="dividerLine">
<img src="images/spacer.gif" height="6" border="0"></td>
</tr>
</table>
<table width="90%" align="center" border="0">
<tr>
<td><img src="images/spacer.gif" height="10" border="0"></td>
</tr>
<tr>
<td align="center" class="PageHeading">
Page-Level Tracing (VB)
</td>
</tr>
</table>
</form>
</body>
</html>
Example 10-2. Code-behind for page-level tracing (.vb)
Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH10TestPageLevelTracingVB.aspx.vb ' ' Description: This class provides the code behind for ' CH10TestPageLevelTracingVB ' '***************************************************************************** Imports System Imports System.Text Namespace ASPNetCookbook.VBExamples Public Class CH10TestPageLevelTracingVB Inherits System.Web.UI.Page '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Const STRING_SECTION As String = "1234567890" Dim testStr As String Dim counter As Integer Dim startTime As DateTime Dim elapsedTime As TimeSpan Dim loops As Integer'output trace message indicating the start of the concatenations
Trace.Write("Page_Load", "Before performing concatenations")
'Measure the elapsed time for 10,000 classic string concatenations loops = 10000 startTime = DateTime.Now( ) testStr = "" For counter = 1 To loops testStr &= STRING_SECTION Next'output trace message indicating the end of the concatenations
Trace.Write("Page_Load", "After performing concatenations")
'calculate the elapsed time for the string concatenations elapsedTime = DateTime.Now.Subtract(startTime)'Write average time per concatenation in milliseconds to trace sequence
Trace.Write("Aver/concat", _
(elapsedTime.TotalMilliseconds / loops).ToString("0.0000"))
End Sub 'Page_Load End Class 'CH10TestPageLevelTracingVB End Namespace
Example 10-3. Code-behind for page-level tracing (.cs)
//---------------------------------------------------------------------------- // // Module Name: CH10TestPageLevelTracingCS.aspx.cs // // Description: This class provides the code behind for // CH10TestPageLevelTracingCS // //**************************************************************************** using System; using System.Text; namespace ASPNetCookbook.CSExamples { public class CH10TestPageLevelTracingCS : System.Web.UI.Page { //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { const string STRING_SECTION = "1234567890"; string testStr = null; DateTime startTime; TimeSpan elapsedTime; int counter; int loops;// output trace message indicating the start of the concatenations
Trace.Write("Page_Load", "Before performing concatenations");
// measure the elapsed time for 10000 classic string concatenations loops = 10000; startTime = DateTime.Now; testStr = ""; for (counter = 1; counter <= loops; counter++) { testStr += STRING_SECTION; }// output trace message indicating the end of the concatenations
Trace.Write("Page_Load", "After performing concatenations");
// calculate the elapsed time for the string concatenations elapsedTime = DateTime.Now.Subtract(startTime);// Write average time per concatenation in milliseconds to trace sequence
Trace.Write("Aver/concat",
(elapsedTime.TotalMilliseconds / loops).ToString("0.0000"));
} // Page_Load } // CH10TestPageLevelTracingCS }