Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Caching - Improve ASP.NET Web Application's Performance

0.00/5 (No votes)
17 Sep 2013 2  
Ways to improve ASP.NET web application's performance

Introduction

This tip will explain approaches to improve an ASP.NET Web application's performance. Application's performance is an important requirement/consideration while designing any application especially when there are going to be 100s and 1000s of requests coming through every second. This tip will introduce some of the ASP.NET framework provided features to help enhance application's performance.

Background

In general, an application’s performance can be improved by saving frequently retrieved data in memory especially when the data was generated as a result of complex programming logic and retrieved from a database or from a file. Saving the retrieved data in memory and displaying the in memory data during successive requests instead of re-performing the complex logic, would enormously improve application’s performance and as well the user experience. For this purpose, ASP.NET framework provides two basic caching mechanisms:

  • Application Caching
  • Output Caching

In this tip, we will see how performance can be improved through application caching. In my next article, we will discuss about Output Caching and its advantages.

Application Caching

Application caching can be implemented using ASP.NET’s Cache class. This class belongs to System.Web.Caching namespace.

Cache items added to the Cache object are private to each application, similar to application state values. Its lifetime is dependent on the application itself, so if the application restarts, the Cache objects will get re-created.

It is very easy to use this Cache class. We will now see how we can add and retrieve items to Cache object and thereby improve application’s performance.

Adding Items to Cache

Only one instance of this Cache object is created for each application domain, and it remains valid as long as the application is active. This object can be accessed either through the HttpContext object or the Cache property of the Page object. Cache object is a key value pair collection and items can be added to Cache in three different ways:

1. Setting the Cache Item Via Key and a Value

Cache[“Key1”] = “Value1”;

The above statement has added an item called “Key1”to the Cache object and its value has been set to “Value1”. The above example sets the cache item “Key1” with a string, but it can be of any object type.

2. Using the Insert Method

The Insert method has 5 overloaded versions.

Let us see an example of retrieving data from an XML file and caching this data unless the file’s content is altered. Let us assume that we have the following weather related data in an XML file:

<?xml
version="1.0" encoding="utf-8"?>
<ArrayOfObservation>
    <Observation>
         <Station>Liverpool</Station>
         <DateTime>2010-09-01T00:00:00</DateTime>
         <Temparature>28.52944896953</Temparature>
    </Observation>
    <Observation>
        <Station>Holsworthy</Station>
    <DateTime>2010-09-01T00:00:00</DateTime>
    <Temparature>30.68702763071</Temparature>
    </Observation>
    <Observation>
         <Station>ChippingNorton</Station>
         <DateTime>2010-09-01T00:00:00</DateTime>
         <Temparature>29.52944896953</Temparature>
    </Observation>
    <Observation>
         <Station>Padstow</Station>
         <DateTime>2010-09-01T00:00:00</DateTime>
         <Temparature>31.68702763071</Temparature>
    </Observation>
</ArrayOfObservation>

To keep it simple, the above file contains weather data for just 4 different suburbs, each record contains Station Name, DateTime and the Temparature details. Let us assume that we would like to present this data in a grid view. Once the data is read from the file, we can data bind it to a GridView control. This data might get updated few times during the day. Instead of reading from the XML file every time a user requests for this data, we could cache the data in the Application’s Cache object and can invalidate it and repopulate it only if the contents of the file have been updated. The following code snippet shows how to use this type of File Dependency:

private void LoadWeatherData() 
{
    if (Cache["WeatherData"] == null)
    {
        DataSet ds = new DataSet();
        string weatherDataFile =  
                 HttpContext.Current.Server.MapPath (@"~\data\WeatherData.xml");
        ds.ReadXml(weatherDataFile);
        GridView1.DataSource = ds;
        GridView1.DataBind();
        CacheDependency cd = new CacheDependency(weatherDataFile);
        Cache.Insert("WeatherData", ds, cd);
    }
    else
    {
        GridView1.DataSource = (DataSet)Cache.Get("WeatherData");
        GridView1.DataBind();
    }
}

Once the item is cached, until, the contents of the file are updated, or the .NET Framework decides to remove the item from the Cache for reasons like low memory, or if the user has explicitly removed the item from the cache, every request to this data will be retrieved from the Cache. Whenever the data in the XML file is updated or the item is removed from the Cache, then the LoadWeatherData method will read from the file and add the item again to the Cache. Though the above example doesn’t involve any complex logic, in places where we might need complex business logic to be used on the data read from the file before presenting it to the user, the caching mechanism would eliminate the reprocessing of the data and would help presenting the data straight from the cache and thus would significantly improve performance.

Note: The above example uses CacheDependency on a file to update the Cache. If the data is retrieved from a database, then we could use SqlCacheDependency mechanism to enable Cache item to be updated when the underlying data table gets updated. We will discuss about this in my future article.

There is another overloaded version of this Insert method which takes a delegate as a parameter (CacheItemRemovedCallback), which gets notified, when the cached data is removed from the Cache object.

The following code snippet shows how the CacheItemRemovedCallback delegate can be used: (The signature of this delegate can be checked from Visual Studio by highlighting this class name and using the “Go To Definition” option from the context menu popup).

The above code checks whether an item called “WeatherData” exists in the Cache object. If it doesn’t exist, then it reads from the XML file and binds the data to the GridView Controller and it also adds the item to the Cache collection. Else it simply binds the data in the Cache object to the GridView Controller.

private void LoadWeatherData()
{
    DataSet ds = new DataSet();
    string weatherDataFile = HttpContext.Current.Server.MapPath(@"~\data\WeatherData.xml");
    ds.ReadXml(weatherDataFile);
    GridView1.DataSource = ds;
    GridView1.DataBind();

    CacheDependency cd = new CacheDependency(weatherDataFile); 
    System.Web.Caching.CacheItemRemovedCallback cacheItemRemovedCallback = 
                           new CacheItemRemovedCallback (onCacheItemRemoved);
    Cache.Insert("WeatherData", ds, null, System.DateTime.Now.AddSeconds(60),     
         System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Default,  
         cacheItemRemovedCallback);
}
public void onCacheItemRemoved(string key, object value, CacheItemRemovedReason reason)
{
   //Add code to inform other controls or parts of the application that the cache item has been 
   // removed
   //The 3rd argument CacheItemRemovedReason is an enumerated data type indicating the 
   //reason why, the item has been removed
}

In addition to the above Insert methods, there are few simple overloaded versions which can be used to either set an absolute expiration time, or a sliding expiration time. Note, both absolute and sliding expiration options can’t be used at the same time.

The following example shows how the inserted item can be cached for a minute using absolute expiration:

HttpContext.Current.Cache.Insert("WeatherData", ds,  null, 
 DateTime.Now.AddSeconds(60),
 System.Web.Caching.Cache.NoSlidingExpiration);

The above statement will remove the Cache item “WeatherData” from the cache after 1 minute. If we want to set a sliding expiration, then the Absolute expiration
should be set to System.Web.Caching.Cache.NoAbsoluteExpiration as shown below:

HttpContext.Current.Cache.Insert("WeatherData ", ds, null, 
   System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 5, 0));

Though we can Cache items in the HttpContext.Current.Cache object, it is not always guaranteed that the Cache item will remain in the Cache object for the predefined time. If the application’s memory is running low, then the .NET framework could decide to remove some of the Cached items. The Cached items can be set with a priority value as shown in the following example:

HttpContext.Current.Cache.Insert("WeatherData", 
      ds, null, System.Web.Caching.Cache.NoAbsoluteExpiration,  new TimeSpan(0, 5, 0),
      System.Web.Caching.CacheItemPriority.NotRemovable, null);

When the priority is set to NotRemovable, then this item will not be removed from the Cache as compared to others even under circumstances where .NET framework decides to remove one or more items from the Cache. But if the Cache item had an expiry time set or if it is dependent on another Cache or file, then it will be removed under such circumstances. The other possible priority values are: Low, Normal, BelowNormal, AboveNormal, High, Default.

3. Using the Add Method

The Add method can also be used instead of Insert method and the Add method also takes all of the above parameters, but there are no overloaded methods which take less parameter as compared to Insert method. As well, the Add method will return an instance of the added Cache object whereas the Insert method wouldn’t. Removing Items from Cache to remove or delete an item from the Cache explicitly, we can use Remove method as follows:

Cache.Remove(“WeatherData”);

The above method would remove the Cache item “WeatherData” from the Cache permanently.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here