ASP.NET provides an extremely handy tool for discovering bottlenecks in your application. Specify trace="true" in the Page directive of your Web form as in the following line:
<% @Page debug="true" trace="true" Language="VB" %>
The next time you load your Web form, you will notice that ASP.NET has automatically printed out a wealth of information for you below your form. In addition to the entire control tree for your form, all server variables and request values, you can see exactly how long each stage of the page's life cycle took. You can see this in Figure 23.1.
The last two columns in the Trace Information section provide the exact (probably more exact than you care to know) amount of time the page object took to load, by stage. So, you can see from Figure 23.1 that the page took approximately 2.86 seconds to load, and approximately 2.78 seconds was spent in the PreRender event.
It's possible to add entries into this list of trace information. By calling Trace.Write() and passing it the category name and your message, not only can you check the value of a particular variable at any given time, but you can also use it to time your events. Look at the code in Listing 23.1. At the beginning of the LoadDataGrid () method, a message is sent to the Trace object denoting the start of data access. After all data access is complete, another message is sent.
Similarly, the DataBind() method of the DataGrid is wrapped, as well. Now, when you load the Web form, it will display these trace entries. You can see the new entries in Figure 23.2.
<% @Page debug="true" trace="true" Language="VB" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <HTML> <HEAD> <LINK rel="stylesheet" type="text/css" href="Main.css"> <!-- End Style Sheet --> <script language="VB" runat="server" > Sub Page_Load(Source as Object, E as EventArgs) LoadDataGrid(orders) End Sub Private Sub LoadDataGrid( _ myDataGrid as System.Web.UI.WebControls.DataGrid) Trace.Write("LoadDataGrid", "Start Data Access") Dim conn as New SqlConnection("Initial Catalog=Northwind;" + _ "Server=(local);UID=sa;PWD=;") Dim cmd as New SqlCommand("SELECT * FROM Suppliers", conn) Dim adapter as SqlDataAdapter = new SqlDataAdapter(cmd) Dim dsSuppliers as New DataSet() conn.Open() adapter.Fill(dsSuppliers) conn.Close() Trace.Write("LoadDataGrid", "End Data Access") Trace.Write("LoadDataGrid", "Begin Data Bind") orders.DataSource = dsSuppliers orders.DataBind() Trace.Write("LoadDataGrid", "End Data Bind") End Sub </script> </HEAD> <BODY> <h1>Tracing Data Access</h1> <hr> <form runat="server" id=form1 name=form1> <asp:DataGrid id="orders" runat="server"></asp:DataGrid> </form> <hr> </BODY> </HTML>
You've seen most of the code in Listing 23.1 many times. However, notice the Trace="true" property specified in the page directive on line 1. This turns on tracing for the Web form. As mentioned before, this will automatically generate a great deal of information located below your form. One such section, shown in Figure 23.2, is named Trace Information. By using the Trace object shown on line 20, you can display your own messages in this section. In addition to enabling you to find bottlenecks in your application, the Trace object is also a terrific way to debug by outputting variable values.
From Figure 23.2, you can see that accessing the data in the Web form took .002115 seconds and the binding of the data lasted for .002404 seconds. Tracing can help you efficiently discover which methods are performing slowly.
Most often, you'll discover that the source of a slow data access method is actually a badly performing database query. In the next section, you'll see how to improve the performance of your database queries using the SQL Query Analyzer tool.