Subscribe

RSS Feed (xml)

Powered By

Skin Design:
Free Blogger Skins

Powered by Blogger


Monday, September 29, 2008

Caching in ASP.NET (Part II)

Caching is an essential feature of ASP.NET that reduces latency and the network traffic by storing frequently used data and pages in the Cache for quick retrieval later; hence greatly boosting the application’s performance. We have had a detailed look at the concepts of Caching in the first part of this series of articles on Caching in ASP.NET. This article presents Data Caching, a feature of ASP.NET that allows you to store your data in the cache memory for faster retrieval. It also discusses the Cache API and the Cache expiration strategies. As in the earlier articles in this series, it also throws light on the related newly added features in ASP.NET 2.0 Caching.

Data Caching using the Cache API

Data Caching is a feature that enables us to store frequently used data in the Cache. The Cache API was introduced in ASP.NET 1.x and was quite exhaustive and powerful. However, it did not allow you to invalidate an item in the Cache based on a change of data in a Sql Server database table. With ASP.NET 2.0, the Cache API provides you a database triggered Cache invalidation technique that enables you to invalidate the data in the Cache based on any change of data in the Sql Server database table. Besides this, you can also create custom cache dependencies.

The Cache class contains a numerous properties and methods. Of these, the Add, Insert, Remove methods and the Count property are the most frequently used. The Add/Insert method of the Cache class is used to add/insert an item into the cache. The Remove method removes a specified item from the cache. The Count property returns the current number of objects in the Cache.

The Cache property of the Page.HttpContext class can be used to store and retrieve data in the cache. The following code snippet illustrates the simplest way of storage and retrieval of data to and from the cache using the Cache class.

//Storing data
Cache ["key"] = objValue;
//Retrieving the data
object obj = Cache ["key"];

We can also check for the existence of the data in the cache prior to retrieving the same. This is shown in the code snippet below:

object obj = null;

if(Cache["key"] != null)
obj = Cache["key"];

The following code snippet illustrates how we can make use of the Cache API to store and retrieve data from the Cache. The method GetCountryList checks to see if the data (list of countries) exists in the cache. If so, it is retrieved from the cache; else, the GetCountryListFromDatabase method fills the DataSet from the database and then populates the Cache.

public DataSet GetCountryList()
{
string key = "Country";
DataSet ds = Cache[key] as DataSet;

if (ds == null)
{
ds = GetCountryListFromDatabase ();
Cache.Insert(cacheKey, ds, null, NoAbsoluteExpiration,
TimeSpan.FromHours(5),CacheItemPriority.High, null);
}

else
{
return ds;
}

} //End of method GetCountryList

public DataSet GetCountryListFromDatabase ()
{
// Necessary code to retrieve the list of countries from the database and
// store the same in a DataSet instance, which in turn is returned to the
// GetCountryList method.
}

Cache Dependency and Cache Expiration Strategies

Cache dependency implies a logical dependency between the data in the Cache and physical data storage. Whenever the data in the physical storage changes, the dependency is broken, the cache is invalidated and the cached item is removed. This physical storage can be an XML file, a database, a flat file, etc.

The following is the complete syntax of using the CacheDependency class.

CacheDependency cacheDependency = new CacheDependency(fileObj, dateTimeObj);
Cache.Insert(key, value, cacheDependency);

As an example, you can set Cache dependency to an external Xml file as shown below:--

Cache.Insert("Country", objDataSet, new CacheDependency(Server.MapPath("Country.xml")));

You can also set a Cache dependency to a file in a remote system as shown below:--

CacheDependency objCacheDependency = new
CacheDependency(@"\\192.168.0.9\joydipk\Test.txt");

Similarly, you can also set Cache dependency on an entire folder. When the contents of the folder changes it will call an event handler for which you need to write the necessary code. In the earlier version of ASP.NET, the CacheDependency class was sealed. Hence you could not subclass this class to create your own Custom Cache dependencies. Things have now changed with ASP.NET 2.0 and the class is no longer sealed so you can create Custom Cache Dependencies by extending this class.

Cache Expiration relates to the removal of data in the cache after the durability of the cached item in the cache has expired. Cache expirations strategies can be Time Based, File Based or Key Based. The following sections discuss each of these strategies in detail with code examples.

Time Based Expiration

This is implemented by specifying a specific duration for which a cached item should remain in the cache. When the time elapses, the item is removed from the cache and subsequent requests to retrieve the item returns a null. This is used to specify a specific period of time for which the page would remain in the cache. The following statement specifies such expiration for a page in the code behind of a file using C# using the Cache API.

Response.Cache.SetExpires(DateTime.Now.AddSeconds(45));

This can also be accomplished by specifying the following in the page output cache directive as shown here.

<%@OutputCache Duration="45"
VaryByParam="None" %>

Time based expiration strategies can in turn be of the following two types:

Absolute
Sliding

In Absolute Expiration, the cache expires at a fixed time/date. For Sliding Expiration the cache duration is increased by the specified sliding expiration value each time the page is requested. Thus a heavily requested page will remain cached, whereas a less requested page will not be cached. Sliding Expiration is therefore useful in ensuring that the valuable resources allocated to the cache are allocated to the most heavily requested pages/items.

The following is an example of Absolute Expiration:

Cache.Insert("Country", ds, null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration);

The cache is set to expire exactly two minutes after the user has retrieved the data.

The following is an example of Sliding Expiration:

Cache.Insert("Country", ds, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(1));

Note that you cannot use both Absolute and Sliding expirations at the same time.


File Based Expiration

This is implemented by using a file as a cache dependency. Whenever the contents of the dependent file are changed, the cached is invalidated. As shown in the code snippet below.

Cache.Insert("Country", obj, new CacheDependancy(Server.MapPath("CountryList.xml")));
Cache.Insert("Country", xmldocumentObject,cacheDependencyObj);

Key Based Expiration

The third type of dependency is the key dependency. This implies that you can map a cache entry to an existing dependency. Now, when the depended-upon entry changes or expires, the dependent entry will also be expired. You can have an array of keys that can be specified as a single CacheDependency. Refer to the code snippet below:

string[] keys = new string[] {"key"};
CacheDependency cacheDependencyObj = new CacheDependency(null,keys);
Cache.Insert("Country", xmldocumentObject,cacheDependencyObj);

Enterprise

Library Caching Application Block

The Patterns and Practices Group of Microsoft’ came up with the reusable, configurable and extensible Enterprise Library Caching Block that enables you to incorporate local cache capabilities in your applications. Microsoft recommends usage of this block when the volume of relatively static data transport is high in your application and performance is a major concern.

The Enterprise Library Caching Application Block facilitates storage of cached data in the memory, isolated storage (i.e., an XML file) or in a database. The Enterprise Library Caching Application Block encapsulates efficient, consistent caching strategies and, hence, simplifies implementation of caching strategies in enterprise application development.

The salient features of the Caching Application Block include:

Support for efficient caching strategies in web applications
Configurable
Thread Safety

Conclusion

Caching is a great tool that can be used to boost the performance of your web applications. Caching in ASP.NET is an effective and powerful way of boosting application performance while minimizing the usage of precious server resources. However, choosing the appropriate type of caching and caching the right type of data goes a long way in designing and developing high performing applications. The fourth and final article in this series will discuss the best practices for Caching in ASP.NET and demonstrates a sample application that will present all the concepts that we have learnt so far in this series.

No comments:

Post a Comment

Recent Posts

Archives