5. Manage Global Data
In ASP and ASP.NET, the Application object represents the global state of the application. It contains data that is visible to all currently running sessions. In ASP.NET, though, the Application-intrinsic object is only one aspect of the Web application: the global state. To learn the best way to manage global data in Web applications, you should first fully understand the underpinnings of the ASP.NET runtime.
The root class of an ASP.NET application is defined in the global.asax
file. Any user code there defines a new class that inherits from HttpApplication. If global.asax
is not specified, the base class HttpApplication
is used as the application class. ASP.NET runtime creates as many instances of the application class as is needed to process simultaneous requests. For most applications, this number falls in the 1-100 range depending on the hardware, the server workload, and the configuration. Instances of the application class are pooled and reused to serve many requests. It is important to notice that application instances are used in a thread-safe manner, one request at a time. This fact has a few important implications.
For one thing, users don't need to worry about locking to access non-static members of the application class. In addition, application code can store per-request data in non-static members of the application class. However, if you store data in members after the EndRequest
event has fired, it keeps the request alivepotentially for a long time. You should just avoid that.
Just like any other class, the application class can have static members, but they are not thread safe. This means that the user code needs to provide appropriate locking around access to such members.
In light of this, there are three ways to store the global state of an ASP.NET application:
- Create a custom HttpApplication
- class and define custom, non-static members
- Define static members in the global.asax file
- Stick to the ASP-style Application dictionary
When you build an application using Visual Studio .NET, the project automatically creates a global.asax.cs
file. It contains the application class derived from HttpApplication, typically named Global. To implement the first option, you can either change the base class to your custom class or add public non-static members to the Global class. Those members are automatically accessed in a thread-safe manner and are strong-typed data.
If you don't use Visual Studio .NET, static members are probably easier to define. A static member, in fact, can be defined directly in the global.asax
file, as shown below.
<script language="C#" runat="server">
public static int Counter = 0;
The Counter member is visible to all sessions as if it were stored in the Application object. To access the property from a page, use the following syntax.
int n = ASP.global_asax.Counter ++;
If you don't particularly like the ASP.global_asax
prefix, you can name the HttpApplication
class using the ClassName
attribute within the @Application
The preceding statement creates an alias for the ASP.global_asax
class (or whatever name your global.asax
class has). The alias, Globals in this sample code, can be used throughout your code wherever ASP.global_asax
Consider that concurrent access to the Counter property is not serialized and you are responsible for inserting any needed lock.
A final word needs to be stated about a couple of very special events, Application_OnStart
. From the perspective of ASP.NET, they aren't even application events but just callbacks made to the user code for classic ASP compatibility. Both events are fired only once per application lifetime, but not for every application instance. This means that changing non-static members in these methods affects only one application instance, not all instances. For this reason, the per-application-instance initialization could be done either in the constructor of the class or by overriding the Init method of the HttpApplication
I started this column blinking at the virtual category of real programmers. In spite of the jokes, real programmers need to be productive but technically straight-to-the-point and knowing the theory behind it all. In this article, I tried to merge a few ASP.NET issues that gave me quite a hard time. I hope that your experience is easier now. Enjoy it!