Flylib.com

Books Software

 
 
 

Chapter 17. State Management

   

Chapter 17. State Management

In this chapter

Using Application and Session Variables

Hidden Fields

Synchronization

Global.asax

Session Information

Demo Application

HTTP, by definition, is stateless. Browsers connect to Web sites, request pages and other data, and then act on the data that they have received from the server. After this data transfer is done, though, there is no more interaction between the client and the server, including shared data and state variables. This is why we say that HTTP is stateless.

Using cookies is one way to maintain some state. But ASP.NET provides an even better mechanism for maintaining a certain amount of state between a client and server, and it has two distinct categories. Client browsers can prevent cookies from being saved by altering the browser user settings ”and when this happens, using cookies to maintain state isn't possible. In the first category, state can be maintained with application variables. Application variables hold data from the time the application starts until the application ends. That is not to say that the data doesn't change; it is to say that the data is maintained in whatever state it happens to be for the life of the application.

Another category of variables that can maintain state is called session variables. These variables contain information about the current session. For example, if a user prefers that all his backgrounds be blue, a session variable could indicate this. And a user might be identified with some sort of unique ID ”this also could be kept in a session variable.

In this chapter, we're going to learn about several topics related to maintaining state. Of course, application and session variables will be important topics. We'll have to talk about synchronizing access to these variables because there will be times when only one client session can access or change the value of a state variable at any given time. The Global.asax file plays an important role in maintaining the values of application and session variables because it contains methods that are called when a session starts and ends, and when an application starts and ends.

   
   

Using Application and Session Variables

Application and session variables work similarly, each having a dictionary of objects. Keys identify each object in the dictionary. The keys are normally text strings that give a name to each object in the dictionary. For example, I might have a user ID object and I might name it UserId . The following simple example shows how an integer value of 12 could be stored in a session variable named UserId :

// C# 

Session["UserId"] = 12; 



' VB 

Session("UserId") = 12

It is just as easy to set a session variable to contain a string. The following examples show how to set session variables in C# and VB to a string containing the name John Doe:

// C# 

Session["UserName"] = "John Doe"; 



' VB 

Session("UserName") = "John Doe"

Session variables can also contain any sort of object that you want to store. To do this, you simply figure out what key name you want to give the session variable, and then assign it to the object. The following examples show how to assign an object into a session variable in C# and VB:

// C# 

Session["SomeGreatObject"] = MyObject; 



' VB 

Session("SomeGreatObject") = MyObject

To create and assign values to an application variable, you do exactly the same thing. Application variables, though, usually apply to the entire application and are thus more global in nature. One of the more common application variables that people use is for traffic counters. The following examples show how to increment a counter in C# and VB:

// C# 

Application["Counter"]++; 



' VB 

Application("Counter") = Application("Counter") + 1

It is sometimes important to check a variable to see whether it is null. Until a variable has been created, it doesn't exist and throws an exception when you try to access it. In C#, you see whether a variable is equal to null, and in VB you see whether it is equal to nothing (with a statement such as myobj = nothing ). The following examples show how to check session and application variables in both C# and VB to see whether they are null and have not yet been created:

// C# 

// Check an application variable for null 

if( Application["SomeKey"] == null ) 

{ 

    // Do something here to initialize the variable 

} 



// C# 

// Check a session variable for null 

if( Session["SomeKey"] == null ) 

{ 

    // Do something here to initialize the variable 

} 



' VB 

' Check an application variable for null 

If Application("SomeKey") = Nothing Then 

    ' Do something here to initialize the variable 

End If 



' VB 

' Check a session variable for null 

If Session("SomeKey") = Nothing Then 

    ' Do something here to initialize the variable 

End If

Application variables are really global variables for an entire ASP.NET application. These variables are available for every user who is currently accessing the application. You should always carefully consider the impact of storing anything as a global variable. Keep the following in mind:

  • Resources that application variables consume

  • Concurrency and synchronization

  • Scalability implications of using application variables

  • The life cycle of application variables

You also want to keep session data to a minimum if possible, especially when a site is a high-traffic site. Session variables as implemented by default take up system memory resources for as long as the session is active. If your site gets hits from 10,000 unique users in a minute, and your session lasts for 20 minutes, you could be storing session data for 200,000 users. If the data stored were 100 bytes, your session data would use 20MB of your system memory. If the data stored were 1000 bytes, the session data would be 200MB. As you can see, this can easily get out of hand.

Resources That Application Variables Consume

The memory occupied by variables stored within application variables isn't released until the value is either removed or replaced . Keeping items in application variables that are not used very often is not a good idea. For example, if you store a recordset that is 10MB or so, and you don't use it very often, this is a very expensive use of these resources.

Concurrency and Synchronization

Multiple running threads within an application can access values stored within application variables simultaneously . This means that you must be careful about accessing these variables. You must ensure that an object stored in an application object is free threaded and contains built-in synchronization support. If you don't do that, and an object in an application is not free threaded, you must perform your own synchronization. To do this, use the Lock() and Unlock() methods .

Scalability Implications of Using Application Variables

You might be forced at times to use locks that protect global resources. Code that runs on multiple threads and accesses these global resources will ultimately end up contending for the resources. This causes the operating system to block some threads while others access the resource. If your server is bearing a heavy load, this can cause severe thread thrashing on the system, which can significantly affect the performance of your Web application.

Life Cycle Implications of Using Application Variables

Developers should be aware that .NET applications can be torn down and destroyed at any moment during application execution. This could be the result of crashes, code updates, scheduled processes restarts, and other things. Global data stored in application state is not durable; it is lost when the host containing it is destroyed . Developers looking to store a state that survives these types of failures should store it in either a database of some sort or some other durable store.