Improving Your Web App's Performance with Aggressive Data Caching

Anyone who has worked on Web applications that use dynamic content knows that data access can be a real bottleneck. One of the nice features in the ASP.NET runtime is its data-caching services via the System.Web.Caching namespace. The challenge most developers face is how to plan ahead for data caching and how to effectively implement it in a way that doesn't over-complicate the code. This article offers a quick review of the features and functions of ASP.NET's data caching. You'll also learn how to build a very simple data-caching "plug-in" assembly in less than 100 lines of code. Finally, you'll see how you can easily use this assembly in your ASP.NET pages to help boost the performance of your Web apps without adding a lot of lines of code.

The Basics of ASP.NET's Data Caching

ASP.NET's data caching provides an in-memory, application-scoped, thread-safe "bucket" that can hold any serializable object or object collection. You can use this feature to hold the results of expensive database queries, large XML documents, and even simple arrays and custom objects you design yourself. Then, during the lifetime of your Web application, you can recall this data from the cache instead of having to go back to the original source every time. Even better, the data cache has features that allow you to set the lifetime of an item in the cache. This enables you to, in some cases, automatically refresh the cache when the underlying data changes.

So, the challenge is to turn this high-powered object into an easy-to-use tool in your Web application toolbox. What you need is a single class that encapsulates the most commonly used features of ASP.NET's data caching and one that provides shortcuts for inserting, refreshing, and recalling data from the cache.

Designing the Cache Utility Class

To make it easier to handle cached items, you can use a simple class to encapsulate key functions and simplify reading, writing, listing, and removing items in the cache. Below is a list of the methods and the associated arguments for each method:

GetCacheItem and DropCacheItem are very simple—they return or remove a selected item. ListCache will return a list of the items in the cache. One version of the method allows you to pass a filter string to control which items are returned. ClearCache will remove either all the items in the cache or just the ones that match the filter string.

The really interesting method is SetCacheItem. It allows you to add an item to the cache and optionally set either a dependency (usually a file name) or a set of expiration values (the maximum life of the object in seconds and/or the maximum idle time of the object in seconds). Dependencies work like this: You can link a cached item to an external item such as a disk file. If that disk file changes, the item is automatically removed from the cache. This is how ASP.NET tracks changes in your WEB.CONFIG files.

Expiration policies are a bit trickier. You can set the lifetime of an object (in this class in seconds). If the object has been in the cache for more than the lifetime, it is automatically removed. You also can set the idle-time of the object (in this class in seconds). If an object has been left idle, meaning no one has requested it, for more than the indicated seconds, it is removed from the cache. The following is the coding for the SetCacheItem method that deals with lifetime and idle time:

The ListCache method returns a simple list (in HTML format) of all the items in the cache. The only challenge to listing items from the cache is that "walking" the Cache collection requires the use of an Enumerator.

This summarizes the basic class that provides easy access to the ASP.NET Cache class. The next step is to create a helper class that uses the basic methods to provide the needed high-level access to the cache collection.

Coding the Cache Object Class

The Cache Utility is nice, but it doesn't really make using the ASP.NET Cache class in a real Web application much easier. For that, you need one more class—a helper class—that provides caching for commonly used data objects. For example, a method that makes it easy to handle a cached DataSet or an XML document. The following code handles a cached DataSet object:

As you can see, this method allows you to pass the information needed to retrieve the DataSet from the cache collection (key), as well as the details needed to create the DataSet (query and connection) and store it in the cache (ttlSeconds and slidingSeconds). You'll even find an argument that allows you to "force" a refresh of the cache (refresh). The first time you use this method in your code, it will find no item in the cache, execute the database query to populate the DataSet, and then place that DataSet into the cache for later use. All subsequent calls will return the item from the cache until the lifetime or idle time is passed. At that time, the data will be retrieved from the database and again placed in the cache.

The code example that accompanies this article also includes other helper methods with optional argument lists to handle various options. The following is a list of those methods:

Now, all that's left is to test this class library in an ASP.NET Web page.

Testing the Cache Library

A simple way to test the library is to build an ASP.NET Web page that displays the results of a DataSet. The following code shows how you can handle a button click event that calls for the display of data from the pubs database in a data bound grid:

As you can see, using this cached version of the DataSet object requires very little extra code. Figure 1 shows the resulting Web page.

Figure 1: ASP.NET Web Page Displaying DataSet Results

The code download that accompanies this article also includes examples of handling XML documents, custom objects, and even simple ArrayList collections using the Cache Library.

What Have You Learned?

In this article, you learned how to use the ASP.NET Caching class to create a simple utility that enables you to cache data from various sources (database, disk files, and so forth) and control their lifetime in the cache. You also saw examples of how to write helper methods that make access to both the data and the cache quick and easy. Finally, you saw an example of how to use these helper classes within an ASP.NET Web page without much extra coding.

The length of this article does not allow for thorough coverage of the System.Web.Caching namespace. Also, the helper class examples in the code cover just a few of the possibilities. By digging into the documentation for the Caching namespace and doing a bit of experimenting on your own, you should be able to expand this simple code example into a powerful utility that will add performance and flexibility to your ASP.NET solutions.

About the Author

Mike Amundsen

An internationally known author and lecturer, Mike Amundsen travels throughout the United States and Europe speaking and teaching on a wide range of software-related topics. He has more than a dozen proramming books to his credit. When he is not working, Mike spends time with his wife and three children at their home in Kentucky, USA.

Top White Papers and Webcasts

Live Event Date: March 19, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT
The 2015 Enterprise Mobile Application Survey asked 250 mobility professionals what their biggest mobile challenges are, how many employees they are equipping with mobile apps, and their methods for driving value with mobility.
Join Dan Woods, Editor and CTO of CITO Research, and Alan Murray, SVP of Products at Apperian, as they break down the results of this survey and discuss how enterprises are using mobile application management and private …

Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …