Application State Management


State management is the persistence of objects or values throughout the lifetime of a web application or for the duration of a user 's interaction with the application. ASP.NET provides four ways to manage state for your application (we will cover each in more detail later in the chapter):

  • User state (session) :User state is controlled through the Session object. Session allows us to maintain data for a limited duration of time (the configurable default is 20 minutes), for a particular user and isolate that data from other users. For example, we could use Session state to track the ad banners we have shown a particular user. If the user doesn't interact with the site within the configurable Session time limit, their data expires and is deleted.

  • Application state :Application state is controlled through the Application object. Application allows us to maintain data for a given ASP.NET application. Settings made in Application are accessible to all resources (ASP.NET page, web services, and so on) within our web application. For example, if we wanted to retrieve some expensive records out of a database and share it throughout our application, storing the data using Application state would be very useful.

  • Transient application state (cache) :Transient Application state is controlled through the Cache object. Cache is similar in functionality to Application , in that it is accessible (shared memory) for the entire web application. H owever, it adds some functionality not available to Application , in the form of dependencies, callbacks, and expiration. For example, when our ASP.NET application started we might populate an object used by all ASP.NET pages from an XML file. We could store this object in the Cache and also create a dependency for that item on the XML file the data originated from. If the XML file changed, ASP.NET will detect the file change and notify the Cache to invalidate the entry. Caching is a very powerful feature of ASP. NET. The differences between Application and Cache are summarized later in the chapter.

  • Static variables :In addition to using the Application or Cache sytate, we can also use one of the object-oriented facilities of ASP.NET “ static variables . When we can declare a static variable, only one copy of the variable is created no matter how many instances of the class are created. The static variable is accessible throughout our application and in some cases is more efficient than Application . This is an advanced option and is discussed at the end of the chapter.

The use of Application and Session (and now Cache ) in ASP.NET is identical to the use of Application and Session in ASP. You can simply use a string key and set a value:

  ' Set an Application value   Application("SomeValue") = "my value"   ' Read an Application value   Dim someString As String   someString = Application("SomeValue")  

These familiar semantics are carried forward and used for the Cache , too:

  ' Set a Cache value   Cache("SomeValue") = "my value"     ' Read a Cache value   Dim someString As String   someString = Cache("SomeValue")  

Let's take a closer look at Session , Application , and Cache and how they relate to building web applications.

Session “ Managing User State

Classic ASP's familiar Session object is new and improved for ASP.NET. The major caveats for Session use in classic ASP are:

  • Web farm challenges : Session data is stored in memory on the server it is created on. In a web farm scenario, where there are multiple web servers, a problem could arise if a user was redirected to a server other than the server upon which they stored their Session state. Normally, this can be handled by an IP routing solution where the IP address of the client is used to route that client to a particular server. However, some ISPs use farms of reverse proxies, where the client request may come through a different IP on each request. When a user is redirected to a server other than the server that contains their Session data, poorly designed applications can break.

  • Supporting clients that don't accept HTTP cookies :Since the Web is inherently a stateless environment, to use Session state the client and web server need to share a key that the client can present to identify its Session data on subsequent requests . Classic ASP shared this key with the client through an HTTP cookie. While this scenario worked well for clients that accept HTTP cookies, it broke for the one percent of users that rejected HTTP cookies.

Both of these issues have been addressed in ASP.NET's Session state, which supports several new features:

  • Web farm support :ASP.NET Session now supports storing the Session data in-process (in the same memory that ASP.NET uses), out-of-process using Windows NT Service (in separate memory from ASP.NET), and in SQL Server (persistent storage). Both the Windows Service and SQL Server solutions support a web farm scenario where all the web servers can be configured to share a common Session store. So, as users get routed to different servers, each server is able to access that user's Session data. To the developer using Session , this is completely transparent and does not require any changes in the application code. Rather, we must configure ASP.NET to support one of these out-of-process options. We will discuss configuring Session state in the next chapter.

  • Cookieless mode :Although somewhat supported in ASP through the use of an ISAPI filter (available as part of the IIS 4.0 SDK), ASP.NET makes cookieless support for Session a first class feature. However, by default, Session still uses HTTP cookies. When cookieless mode is enabled (details in the next chapter), ASP.NET will munge the URL that it sends back to the client with a Session ID, rather than storing the Session ID in an HTTP cookie. When the client makes a request using the munged URL containing the Session ID, ASP.NET is able to extract it and map the request to the appropriate Session data.

We will cover how to configure both of these options in the next chapter, when we discuss ASP.NET configuration. From our perspective as developers coding and using Session , these features are completely transparent.

Session is dedicated data storage for each user within an ASP.NET application. It is implemented as a Hashtable and stores data based on key/value pair combinations.

Setting Session Value

In ASP.NET, the use of Session follows the same pattern as in classic ASP. To set a Session value in Visual Basic .NET, simply state:

  Session("[String key]") = Object  

The C# equivalent is:

  Session["[String key]"] = Object;  

You can provide Session with a key that identifies the item we are storing. This Session stores items of type Object . Since all types in .NET inherit from Object , this allows you to store anything in Session . However, objects that contain live references, such as a DataReader containing an open connection to a database, should not be stored in Session .

For example, to store the string Hello World using a key of SimpleSession , write the following code in Visual Basic .NET:

  Session("SimpleSession") = "Hello World"  

And in C#:

  Session["SimpleSession"] = "Hello World";  

Underneath the covers, the CLR knows that the type String originated from the type Object , and is able to store that value correctly in memory.

Retrieving Session Value

Since Session is available throughout your web application, you can set values in global.asax code and access a Session value from ASP.NET pages.

For example, to retrieve your Hello World value from Session , you only need to provide Session with your key for it to return the value. This is the Visual Basic .NET code:

  Dim sessionValue As String   sessionValue = Session("SimpleSession")  

And in C#:

  string sessionValue;   sessionValue = Session["SimpleSession"];  

For types other than String , the semantics of accessing the value stored in Session are a bit more explicit. Because Session stores its data as an Object type, giving it the flexibility to store any .NET item, when you wish to retrieve data (other than type String ) you have to cast the return value to the correct type.

For example, if you stored a custom class you defined called PurchaseOrder in Session , here is how you would need to retrieve it in Visual Basic .NET:

Important

For a class instance to be stored in out-of-process Session state, the class must be marked with the [Serializable] attribute.

  Dim po As PurchaseOrder   po = CType(Session("po"), PurchaseOrder)  

And in C#:

  PurchaseOrder po;   po = (PurchaseOrder) Session["po"];  

In both examples, the Object returned is cast by the key po to type PurchaseOrder .

The Session API provides additional properties that you can use in code to determine what mode Session is in:

  • IsCookieless :Returns True or False indicating whether or not Session is using cookieless mode to maintain the Session ID. By default, this is False , meaning that Session is using cookies.

  • IsReadOnly :Returns True or False indicating whether or not Session is in read-only mode. Read-only mode is an optimization that does not allow ASP.NET to update Session data. This can be particularly useful for out of process modes on pages that only read Session state and don't need write access. When a Session is read-only, a lock does not have to be maintained and the round-trip back to an out-of-process Session store for an update can be skipped . By default, this value is False , and Session is read/write. We will discuss how to enable ReadOnly for Session in the next chapter.

  • Mode :Returns the value of an enumeration, SessionStateMode , (found in System.Web.SessionState ) that indicates the storage mode that Session is configured for. Values include InProc , Off , SQLServer , and StateServer .

ASP.NET session state is quite different from ASP session state. The new capability of session state that is not bound to the ASP.NET process means that developers can begin to use session state in server farm environments without worrying about whether the client is coming through a proxy server. With the cookieless state functionality, it is even easier to use session state and guarantee that all clients can take advantage of the session state feature. In the next chapter, you will learn how to configure Session to support a read-only mode as well the other 'mode' options (in-process, Windows Service, and SQL Server).

Configuring and using Session State is covered in more depth in Chapter 13.

Application “ Managing Application State

Unlike Session , which is basically dedicated storage for each user, Application is shared application storage. This shared storage is quite useful, especially if there are resources that all users share, such as an XML representation of a site's shopping catalog. Similar to Session , Application state is simply a Hashtable that stores key/value pair combinations.

Unlike Session , however, Application does not support the concept of storing data separate from the ASP.NET process. Instead, Application stores its data in process with ASP.NET. If the ASP.NET process is recycled (covered in the next chapter) Application data is lost. The trade-off is that storing the data in-process is faster than going to another process, or possibly across the network, to retrieve data.

The syntax used for setting and accessing values with Application is identical to that of Session , with one exception.

Since Application is accessible in a multi-user environment, updates to Application values should be synchronized . This simply means that whenever Application data is being updated, you should prevent other users or applications from updating the data simultaneously . Luckily, Application provides you with this capability through a simple set of locking methods. Note these are the same locking methods Lock and UnLock supported in ASP.

Reading and Writing Application Data

We read and write data in Application in a similar manner to Session using key/value pairs, such as the following in Visual Basic .NET:

  Application("HitCounter") = 10  

Or in C#:

  Application["HitCounter"] = 10;  

Similarly, if you wish to read the value back simply use your key, like this in Visual Basic .NET:

  Dim HitCount As Integer   HitCount = Application("HitCounter")  

Or in C#:

  int HitCount = Application["HitCounter"];  

However, to update HitCounter you must synchronize access using the Lock and UnLock methods of Application . Otherwise, the potential exists for two requests to attempt to update HitCounter simultaneously, causing a potential deadlock or update failure.

Although this is an illustrative example, when you Lock, you are effectively blocking other applications that may be attempting to update the HitCounter value, causing them to serialize “ that is, perform operations one after another. We definitely don't want to Lock/UnLock on each request, as this would negatively affect performance. If the data stored in Application must be updated frequently, it is probably not a good candidate for Application state, unless recreating the data is more costly than the time spent serializing the updates.

Let's look at an illustrative example using Application.Lock and Application.UnLock , first in Visual Basic .NET:

  Public Sub Application_OnStart()   Application("HitCount") = 0   End Sub     Public Sub Application_OnBeginRequest()   Application.Lock()   Application("HitCounter") = Application("HitCounter") + 1   Application.UnLock()   End Sub  

And now in C#:

  public void Application_OnStart() {   Application["HitCounter"] = 0;   }     public void Application_OnBeginRequest(){   Application.Lock();   int tmpInt = (int)Application["HitCounter"];   Application["HitCounter"] = tmpInt + 1;   Application.UnLock();   }  

In the preceding code, we call Application.Lock to ensure that while we update HitCounter , some other thread cannot update the value simultaneously.

Note

When the ASP.NET process is stopped or recycled, Application state is lost. However, when the process is recycled, the Application_OnEnd event (discussed later) is raised and values can be persisted to a database or file.

Since ASP.NET is a multi-threaded system, Application memory can be accessed by multiple processes simultaneously. To use Application and set values, you must either:

  • Know that the object stored in Application is doing its own thread management (not shown).

    Or

  • Perform our own synchronization using Application.Lock and Application.UnLock .

Calling Lock instructs ASP.NET to block any other threads from modifying this resource until UnLock is called, giving your code exclusive access. However, if you don't explicitly call UnLock , ASP.NET will call it when the application completes the request, the request times out, or an unhandled error occurs. Although this is done for us, you should always aim to write code that explicitly calls UnLock .

Storing Objects in Application

Classic ASP VB objects could not be hosted in Application state due to the default threading model these components supported ( Apartment Model threading ). In effect, accessing an instance of a VB component stored in Application would cause ASP to serialize (execute one request after another) access to that component. .NET components are free threaded by default and don't have this thread affinity problem. Therefore, there are no performance penalties for storing a Visual Basic .NET object in Application and accessing it across multiple requests.

Next, let's look at a new object, Cache , used to store transient application data.

Cache “ Managing Transient State

Many developers use Application as a cache for frequently used resources, for example, reading an XML file that represents a product catalog and storing the object representing that XML file in Application memory.

However, what happens when this XML file representing the product catalog changes? In most cases, developers who use Application to manage this data simply force the web application to restart, thus forcing Application to get refreshed.

The design goal of the Cache was to give developers the benefits of Application , but with additional features that went above and beyond those provided by Application , such as the ability to evict an item from the Cache when a file changes, it is then your responsibility through code to add the item back to the Cache if you desire .

Cache Overview

Cache is an instance of the Cache class found in the namespace System.Web.Caching . In addition to being a simple key/value pair Hashtable like Application , the Cache also supports:

  • Dependency-based expiration :Dependencies can be other Cache keys, files, or a timestamp. When one of the dependencies changes or expires (timestamp), the Cache item is invalidated and removed from the Cache .

  • Lock management :Unlike Application , the Cache class does its own internal lock management. Therefore, while Application required us to explicitly Lock and UnLock when updating Application , Cache doesn't require this. Keep in mind that we do still need to manage concurrency for objects stored in the Cache just as we do with objects stored in Application .

  • Resource management :When the Cache detects memory pressure, a least recently used algorithm walks the Cache and automatically evicts items used less frequently. Therefore, before we request an item, we always need to check if the item exists.

  • Callbacks :The Cache supports allows us to run code when items are removed from the Cache .

The Cache supports two methods of inserting items:

  • Implicit :We are familiar with this syntax from working with Session or Application using the key/value pairs.

    In Visual Basic .NET:

      Dim productDataSet As New DataSet()   ' Populate DataSet   Cache("products") = productDataSet  

    And in C#:

      DataSet productDataSet = new DataSet();   // Populate DataSet   Cache["products"] = productDataSet;  
  • Explicit :Using the Insert method, it allows us to set up special relationships such as dependencies. In VB.NET, the code to do this is.

      Dim productDataSet As New DataSet()   ' Populate DataSet   Cache.Insert("products", productDataSet, Nothing)  

    In C#:

      DataSet productDataSet = new DataSet();   // Populate DataSet   Cache.Insert("products", productDataSet, null)  

The Cache also supports an Add method. The Add method behaves similar to Insert , with the exception that it will only add them item to the Cache if it does not already exist “ whereas the Insert method will always add the item into the Cache , even if it already exists.

When using the Cache , you will mostly use the explicit Insert . Let's look at some examples.

Dependency-Based Expiration

Dependency-based expiration is very powerful. It allows you to create a relationship between an item in the Cache and either a file, another Cache key, or a defined point in time. For example, if your site used XML and XSL transforms to control aspects of content, you could load the XML into an XmlDocument class and store the value within the Cache . You could also establish a relationship between the cached XmlDocument and the file that it is reading, using the file-based dependency feature of the Cache . Let's build this sample.

This is the XML file:

  <?xml version="1.0"?>   <books>   <book>   <name>Professional ASP.NET 2nd Edition</name>   <isbn>1861007035</isbn>   <publisher>Wrox Press</publisher>   <authors>   <author name="David Sussman"/>   <author name="Brian Francis"/>   <author name="Alex Homer"/>   <author name="Karli Watson"/>   <author name="Rich Anderson"/>   <author name="Rob Howard"/>   </authors>   <description>   ASP.NET is a unified web development   platform that provides the services necessary   for developers to build enterprise-class web   applications.   </description>   </book>   </books>  

The file is saved as 1861007035.xml , which is the ISBN for the book Professional ASP.NET 1.0 Special Edition. You also have an XSL transform for this file, called book.xsl :

  <xsl:stylesheet   version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:output method="html"/>   <xsl:template match="/">   <html>   <head>   <title><xsl:value-of select="books/book/name"/></title>   </head>   <style>   body { font-family: Arial; font-size: 18; color:white; }   li { list-style: square outside; }   </style>   <body bgcolor="black">   <xsl:apply-templates/>   </body>   </html>   </xsl:template>   <xsl:template match="name">   <h1><font color="red"><xsl:value-of select="."/></font></h1>   </xsl:template>   <xsl:template match="description">   <h6><xsl:value-of select="."/></h6>   </xsl:template>   <xsl:template match="isbn">   <font size="1">ISBN: <xsl:value-of select="."/></font><br/>   </xsl:template>   <xsl:template match="publisher">   <font size="1">Publisher: <xsl:value-of select="."/></font><br/>   </xsl:template>   </xsl:stylesheet>  

The following code snippet is the ASP.NET page ( SingleFilevb.aspx ) that uses the Cache and creates a file dependency on the XML file only “ in this particular example we are not caching the XSL file:

  <%@ Import Namespace="System.Xml" %>   <%@ Import Namespace="System.Xml.Xsl" %>     <Script runat="server">   Public Sub Page_Load(sender As Object, e As EventArgs)   Dim dom As XmlDocument   Dim xsl As New XslTransform()     ' Do we have the Wrox Pro ASP.NET 2nd Ed book in the Cache?   If (IsNothing(Cache("1861007035.xml"))) Then   CacheStatus.Text = "Item not present, updating the Cache..."   UpdateCache("1861007035.xml")   Else   CacheStatus.Text = "Retrieving from Cache"   End If     ' Load the transform   xsl.Load(Server.MapPath("book.xsl"))     dom = CType(Cache("1861007035.xml"), XmlDocument)     BookDisplay.Document = dom   BookDisplay.Transform = xsl     End Sub     Public Sub UpdateCache(strItem As String)     Dim strPath As String   Dim dom As New XmlDocument()     ' Determine the file path of the file to monitor   strPath = Server.MapPath(strItem)     ' Load the file into an Xml Dom   dom.Load(strPath)     ' Create a CacheDependency on the file   Dim dependency as New CacheDependency(strPath)     ' Cache the XML document   Cache.Insert(strItem, dom, dependency)   End Sub   </Script>   Status: <asp:label id="CacheStatus" runat=server/>   <br>   <asp:xml id="BookDisplay" runat=server/>  

The interesting code appears in the UpdateCache subroutine, which is called if the Cache key 1861007035.xml is not present. We first map the path to the XML file, which is in the same directory, and load that XML file into an XmlDocument class. Then, we create a new CacheDependency class passing in the path to the XML file. Finally, we use the Cache's Insert method and create a new Cache entry using the name of the file ( 1861007035.xml ), the XmlDocument instance, dom , and the CacheDependency class instance, dependency .

On requesting this page for the first time, you would see the screen shown in Figure 12-9:

click to expand
Figure 12-9:

On subsequent requests you would see the Status: Retrieving from Cache message.

If you open the 1861007035.xml file and modify the name from Professional ASP.NET 1.0 Special Edition to Pro ASP.NET 1.0 , the file change notification would be enforced and the XmlDocument storing the XML from the file would be removed from the Cache . Requesting the ASP.NET page would bring up the screen shown in Figure 12-10:

click to expand
Figure 12-10:

What if instead of monitoring a file, you wanted to remove an entry (or series of entries) from the Cache when another item in the Cache changed? This option is supported through a key-based dependency.

The syntax for supporting key-based dependencies is very similar to that used in file-based dependencies. For example, you can easily change the preceding code to support a key-based dependency by modifying only a couple of lines.

If you cached multiple XML documents for each Wrox book on .NET, you could set up a dependency relationship where the Cache entries for the books could be invalidated (and reloaded) whenever a master key, for example booksDependencyKey , changed.

The following code example, called KeyBasedvb.aspx , creates such a relationship:

  <%@ Import Namespace="System.Xml" %>     <Script runat="server">     Public Sub Create(sender As Object, e As EventArgs)   ' Create the Cache entry for the dependency relationship   ' the value of the key doesn't matter   Cache("booksDependencyKey") = "Book Dependency"     ' Create a string array with the key names for the   ' dependencies to be created upon   Dim dependencyKey(0) As String     dependencyKey(0) = "booksDependencyKey"     ' Create a CacheDependency on this key   Dim dependency as New CacheDependency(nothing, dependencyKey)     ' Cache the XML document   Cache.Insert("1861007035.xml", Load("1861007035.xml"), dependency)     Status()   End Sub     Private Function Load(xmlFile As String) As XmlDocument   Dim dom As New XmlDocument()   dom.Load(Server.MapPath(xmlFile))   Return dom   End Function     Public Sub Invalidate(sender As Object, e As EventArgs)   Cache.Remove("booksDependencyKey")   Status()   End Sub     Public Sub Status()   If (IsNothing(Cache("1861007035.xml"))) Then   lblStatus1.Text = "No value..."   Else   lblStatus1.Text = "Cache entry exists..."   End If   End Sub     </Script>   <form runat=server>   <input type="submit" OnServerClick="Create"   value="Create Cache Entries" runat="server" />   <input type="submit" OnServerClick="Invalidate"   value="Invalidate Key" runat="server" />   </form>   Status for cache key: 1861007035.xml: <b><asp:label id="lblStatus1"   runat=server/></b>  

When you run this code, you need to press the Create Cache Entries button to create the Cache entry for the XML file, as well as the dependency relationship. You can then press Invalidate Key, which raises the Invalidate event. Within this event, we explicitly remove the cache key booksDependencyKey . This enforces the dependency and also removes the Cache entry for your XML document.

Finally, in addition to file and key-based dependencies, you can also create dependencies on time values. Consider an example where Wrox were to store all of its book titles in a single table in the database, and you knew that this data was only updated once a week. You could cache a DataSet that represents this data with an explicit expiration of 60 minutes. This will save you going to the database for every request, but in case an update occurs, you can still guarantee that the data will be fresh within the following hour .

Here's the code from TimeBasedvb.aspx that does this:

  <%@ Import Namespace="System.Data" %>   <%@ Import Namespace="System.Data.SqlClient" %>     <script runat=server>   Private DSN As String     Public Sub Page_Load(sender As Object, e As EventArgs)   Dim strCacheKey As String   Dim titlesDataSet As DataSet     strCacheKey = "Titles"     If (IsNothing(Cache(strCacheKey))) Then   lblStatus.Text = "Getting data from database..."   LoadTitles(strCacheKey)   Else   lblStatus.Text = "Getting data from Cache..."   End If     titlesDataSet = CType(Cache(strCacheKey), DataSet)   TitleList.DataSource = titlesDataSet   TitleList.DataBind()     End Sub     Public Sub LoadTitles(strCacheKey As String)   Dim connection As SqlConnection   Dim command As SqlDataAdapter   Dim sqlSelect As String   Dim strDsn As String   Dim dataset As New DataSet()     sqlSelect = "SELECT title, pub_id, price, notes, pubdate FROM titles"   strDsn = "server=localhost;uid=sa;pwd=;database=pubs"     connection = New SqlConnection(strDsn)   command = New SqlDataAdapter(sqlSelect, connection)     command.Fill(dataset, "Author-Titles")   Cache.Insert(strCacheKey, dataset, nothing, _   DateTime.Now.AddMinutes(60), TimeSpan.Zero)   End Sub   </script>   <font size=6>   <asp:label id="lblStatus" runat="server"/>   </font>   <P>   <ASP:DataGrid id="TitleList" HeaderStyle-BackColor="#aaaadd"   BackColor="#ccccff"   runat="server" />  

In this example, we have some logic at the beginning that checks for an entry in the Cache named Titles . If the Cache entry doesn't exist, we then call the subroutine LoadTitles , which connects to a database, performs a select on the titles table, fills a DataSet , and finally inserts the DataSet into the Cache . We are using the explicit Insert method of the Cache :

 Cache.Insert(strCacheKey, dataset, nothing, _              DateTime.Now.AddMinutes(60), TimeSpan.Zero) 

This adds a Cache entry with the key titles , the populated dataset , and also instructs the cache to expire the item after 60 minutes.

Cache additionally supports a very useful callback capability. The callback allows you to run your code when an item is removed from the cache, giving you the opportunity to add it back.

We could make the following modification to the preceding code (highlighted), which would guarantee that our item is always served from the cache:

 ...  If (loadedFromCallback) Then   lblStatus.Text = lblStatus.Text + "loaded from callback"   loadedFromCallback = false   End If  sqlSelect = "SELECT title, pub_id, price, notes, pubdate FROM titles"    connection = New SqlConnection("server=localhost;uid=sa;pwd=00password;database=pubs")    command = New SqlDataAdapter(sqlSelect, connection)    command.Fill(dataset, "Author-Titles")  ' Create the a CacheItemRemovedCallback   Dim onRemove As New CacheItemRemovedCallback(AddressOf _   Me.RemovedCallback)   Cache.Insert(strCacheKey, dataset, nothing,   DateTime.Now.AddMinutes(60), TimeSpan.Zero, _   CacheItemPriority.High, onRemove)  End Sub  ' This method represents the callback   Public Sub RemovedCallback(key As String, value As Object,   reason As CacheItemRemovedReason)   ' Let's always re-add the item if removed   LoadTitles(key)   End Sub  </script> <font size=6> <asp:label id="lblStatus" runat="server"/> </font> <P> <ASP:DataGrid id="TitleList" HeaderStyle-BackColor="#aaaadd" BackColor="#ccccff"               runat="server" /> 

Caching adds a lot of powerful new features to manage data that you ordinarily would have stored in Application state. Dependencies allow you to set up relationships with items that can invalidate the cache, and callbacks allow you to execute your own code whenever an item is removed from the Cache .

State management in ASP.NET should be very familiar to developers who have worked with ASP. Both Session and Application state remain identical in use and you now have the Cache option. It is very important to understand state management and when to use the options provided by it. Here are some basic guidelines:

  • Session :Used to store data that should be available to the user on each request. Be efficient about what you store in Session , since each Session will get its own individual copy of the data. Remember that class instances stored in out-of-process session state must be attributed with the [Serializable] attribute at the class level.

  • Application :Used to store data that needs to be available to the entire application. A good candidate for Application is data that remains fairly static and must be available on each request. Remember to use the Lock and Unlock methods to control access to Application when updating the data.

  • Cache :Used to store data that may be used on each request, or data where a dependency relationship needs to be established. In many cases, Cache can be used in place of Application .




Professional ASP. NET 1.1
Professional ASP.NET MVC 1.0 (Wrox Programmer to Programmer)
ISBN: 0470384611
EAN: 2147483647
Year: 2006
Pages: 243

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net