Caching

ASP.NET provides support for "caching" which can cache [store in memory] the output generated by a page and will serve this cached content for future requests.This is useful where the page content is the same for all requests [user-independent]. The caching feature is customizable in various ways and we will see how we can do that as we go through this article.

Caching a page

In order to cache a page's output, we need to specify an @OutputCache directive at the top of the page. The syntax is as shown below:

<%@ OutputCache Duration=5 VaryByParam="None" %> 
 
 Duration - The time in seconds of how long the output should be cached. After the specified duration has elapsed, the cached output will be removed and page content generated for the next request.
 VaryByParam - This attribute is compulsory and specifies the querystring parameters to vary the cache. In the above snippet, we have specified the VaryByParam attribute as None which means the page content to be served is the same regardless of the parameters passed through the querystring
 If there are two requests to the same page with varying querystring parameters, e.g.: .../PageCachingByParam.aspx?id=12 and .../PageCachingByParam.aspx?id=15] and separate page content is generated for each of them, the directive should be:

<%@ OutputCache Duration=5 VaryByParam="id" %>

 The page content for the two requests will each be cached for the time specified by the Duration attribute
To specify multiple parameters, use semicolon to separate the parameter names. If we specify the VaryByParam attribute as *, the cached content is varied for all parameters passed through the querystring.

Some pages generate different content for different browsers. In such cases, there is provision to vary the cached output for different browsers. The @OutputCache directive has to be modified to:

<%@ OutputCache Duration=5 VaryByParam="id" VaryByCustom="browser" %>
 
This will vary the cached output not only for the browser but also its major version. I.e., IE5, IE 6, Netscape 4, Netscape 6 will all get different cached versions of the output.

 

Caching page fragments


Sometimes we might want to cache just portions of a page. For example, we might have a header for our page which will have the same content for all users. There might be some text/image in the header which might change everyday. In that case, we will want to cache this header for a duration of a day.
The solution is to put the header contents into a user control and then specify that the user control content should be cached. This technique is called fragment caching.
To specify that a user control should be cached, we use the @OutputCache directive just like we used it for the page.

<%@ OutputCache Duration=10 VaryByParam="None" %>
 
With the above directive, the user control content will be cached for the time specified by the Duration attribute [10 secs]. Regardless of the querystring parameters and browser type and/or version, the same cached output is served. 

Data Caching


ASP.NET also supports caching of data as objects. We can store objects in memory and use them across various pages in our application. This feature is implemented using the Cache class. This cache has a lifetime equivalent to that of the application. Objects can be stored as name value pairs in the cache. A string value can be inserted into the cache as follows:

Cache["name"]="Smitha";
 
The stored string value can be retrieved like this:

if (Cache["name"] != null)
    Label1.Text= Cache["name"].ToString();
 

To insert objects into the cache, the Add method or different versions of the Insert method of the Cache class can be used. These methods allow us to use the more powerful features provided by the Cache class. One of the overloads of the Insert method is used as follows:

Cache.Insert("Name", strName, 
    new CacheDependency(Server.MapPath("name.txt"), 
    DateTime.Now.AddMinutes(2), TimeSpan.Zero);
 
The first two parameters are the key and the object to be inserted.

The third parameter is of type CacheDependency and helps us set a dependency of this value to the file named name.txt. So whenever this file changes, the value in the cache is removed. We can specify null to indicate no dependency.

The fourth parameter specifies the time at which the value should be removed from cache. [See example 5 for an illustration.]

The last parameter is the sliding expiration parameter which shows the time interval after which the item is to be removed from the cache after its last accessed time.

The cache automatically removes the least used items from memory, when system memory becomes low. This process is called scavenging. We can specify priority values for items we add to the cache so that some items are given more priority than others:

Cache.Insert("Name", strName, 
    new CacheDependency(Server.MapPath("name.txt"), 
    DateTime.Now.AddMinutes(2), TimeSpan.Zero, 
    CacheItemPriority.High, null);
 
The CacheItemPriority enumeration has members to set various priority values. The CacheItemPriority.High assigns a priority level to an item so that the item is least likely to be deleted from the cache.