Home   |  Articles   |  Resources   |  Humor   |  Feedback       

  Login   Register 

Ads Via DevMavens


Global.asax and the HttpApplication class

Posted by on Saturday, January 24, 2004

The Global class derived from HttpApplication has many uses, including managing application and request state.

The global.asax file setup by Visual Studio.NET gives every web application a Global class derived from HttpApplication. The class contains event handlers such as Application_Start and Session_Start.

There is a tendency to think each web application will have a single instance of Global. Indeed, in most frameworks an object representing the “application” is a singleton – only one exists. Also, we know the ASP.NET runtime calls Application_Start only once when the application starts. All of these clues seem to imply there would be only one instance of a Global object in our application, but these clues are actually misleading.

The ASP.NET runtime maintains a pool of HttpApplication objects. When an incoming request arrives, the runtime takes an HttpApplication object from the pool to pair with the request. The object remains associated with the request, and only that request, until the request processing is complete. When the request is finished the runtime may return the object to the pool, and later pull it out to service another request later – but only one request at a time is associated with an HttpApplication object.

Application State versus Request State

The Application object (of type HttpApplicationState) is what we generally think of when we need to store information global to the application. The Application object is a convenient place to store information such as a database connection string.

private void Page_Load(object sender, System.EventArgs e)
{
    string connectionString = 
         Application["ConnectionString"].ToString();
    . . . . 
}

You can also make your own static variables in the HttpApplication class to carry application state. For example, the above information could also be stored like this:

public class Global : System.Web.HttpApplication
{
    public static 
       readonly string ConnectionString = "connection information";

    . . .    
}

You can access the member from anywhere in your ASP.NET code like so:

    
string connectionString = Global.ConnectionString;

It is important to make the string a static member (you could also make a static property accessor) if you want the member to be global for the application.

If you instead use member (non-static) variables, you can use these for request state. For instance, the following code will print out the number of milliseconds used to process a request in the output window of the debugger.

    
public class Global : System.Web.HttpApplication
{

   protected DateTime beginRequestTime;

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        beginRequestTime = DateTime.Now;
    }

    protected void Application_EndRequest(Object sender, EventArgs e)
    {
       string messageFormat = "Elapsed request time (ms) = {0}";
       TimeSpan diffTime = DateTime.Now - beginRequestTime;
       Trace.WriteLine(
                String.Format(
                    messageFormat, diffTime.TotalMilliseconds
                 )
         );                      
    }
    . . . 
}

Now, returning to the question of application state. Which is better: storing object references in the Application object, or making static member variables and properties in the Global class? Both approaches have pros and cons.

Keeping global data in static members of the Global class gives you strong typing. Unlike the Application object, you will not need to typecast or convert values. It is the difference between the following two sections:

	
DataSet cachedData = (DataSet)Application[“MyDataSet”];
string myString = Application[“MyString”].ToString();

DataSet cachedData = Global.MyDataSet;
string = Global.MyString;

Strong typing gives you cleaner, more robust code. In performance critical situations it can also save the overhead of running conversions. If you are storing value types, such as integers, strong typing avoids the overhead of boxing and unboxing the value into an object (see references). Also, as mentioned in a previous article, the Application object also has some small overhead due to locking. If you initialize your global data only once and never modify or write to the data, you can avoid the locking overhead with static members on the Global class. If you take this approach, I recommend using accessor properties with only get methods to make sure the data is read only.

If you read as well as write static members of the Global class, remember to be thread safe. The Application object already provides thread safety through a course grained reader / writer lock.

The safest place to initialize the global data is during the Application_Start event.Even though there are multiple instances of the Global object around, the runtime only invokes Application_Start on the first instance of Global it creates. An ideal time to initialize request state is during Application_BeginRequest. Request state variables generally do not require thread safety, as each object services only one request at a time.


by K. Scott Allen (scott @ OdeToCode.com)

Additional references:

INFO: Application Instances, Application Events, and Application State in ASP.NET

Working with HttpApplication Instances

HttpApplication Events

FIX: HttpApplication.OnThreadEnter May Fail Under Memory Pressure

Open the Box! Quick!

 


Copyright 2004 OdeToCode.com 


The Blogs
Subscribe to the OdeToCode blogs for the latest news, downloads, new articles, and quirky commentary.
New Articles
Databinding in Silverlight
This article will cover data binding features in Silverlight, including binding expressions, validation, converters, and binding modes.

The Standard LINQ Operators
This article will cover the standard LINQ operators provided by LINQ for filtering, grouping, joining, converting, projecting, and more.

C# 3.0 and LINQ
C# 3.0 introduced a number of new features for LINQ. In this article we'll examine the new features like extension methods, lambda expressions, anonymous types, and more.

Most Popular Articles
Table Variables In T-SQL
Table variables allow you to store a resultset in SQL Server without the overhead of declaring and cleaning up a temporary table. In this article, we will highlight the features and advantages of the table variable data type.

ASP.Net 2.0 - Master Pages: Tips, Tricks, and Traps
MasterPages are a great addition to the ASP.NET 2.0 feature set, but are not without their quirks. This article will highlight the common problems developers face with master pages, and provide tips and tricks to use master pages to their fullest potential.

AppSettings In web.config
In this article we will review a couple of pratices to keep your runtime configuration information flexible.

Contribute Code
Privacy
Consultancy