Caching is a technique of storing an in-memory copy of important and much used data/information to improve the performance of any software system. The idea is to place frequently used data in quickly accessed media. The ASP.Net runtime includes a key-value map of CLR objects called cache. This lives with the application and is available via the HttpContext and System.Web.UI.Page. Using cache is to some extent similar to using Session object. You can access items in the cache using an indexer and may control the lifetime of objects in the cache and set up links between the cached objects and their physical sources.
Caching in ASP.Net
Introduction
Caching is a technique of storing an in-memory copy of important and much used data/information to improve the performance of any software system. The idea is to place frequently used data in quickly accessed media. The ASP.Net runtime includes a key-value map of CLR objects called cache. This lives with the application and is available via the HttpContext and System.Web.UI.Page. Using cache is to some extent similar to using Session object. You can access items in the cache using an indexer and may control the lifetime of objects in the cache and set up links between the cached objects and their physical sources.
ASP.Net Caching
ASP.Net provides two types of caching which complement each other.
1. Output Caching: Output cache stores a copy of the finally rendered HTML page sent to the browser. When the next client requests for this page, the page is not actually run instead the cached copy of the HTML is sent thus saving time.
2. Data Caching: Data cache stores pieces of information like DataTable or DataSet retrieved from a database. Data caching is similar to application state, but it is more server friendly. Because, cache items could be removed from the server memory if it grows large and affects performance. Items can also be set to expire automatically.
The following types of caching are built on these two models.
· Fragment caching: instead of caching the entire HTML page, you can cache a portion of it
· Data source caching: this is built into the data source controls like—the SqlDataSource, ObjectDataSource and XmlDataSource. You need to configure the appropriate properties and the data source control manages the caching storage and retrieval.
Output Caching
The whole page rendering process can be pretty involved like the page may require database access, may have lots of controls on it, some of these might be complex like a DataList or GridView making the rendering process expensive. As you bypass the round trips to database by caching data in memory, you can use output caching to bypass the whole page rendering.
To set up output caching you need to place the OutputCache directive on the page. It’s a separate directive like the Page directive. It enables caching and provides certain control over its behaviour.
To understand this, let us create a small application, where under the Page directive, you add this line:
<%@ OutputCache Duration="15" VaryByParam="None" %>
This tells the environment to cache the page for 15 seconds. To check that the page was really cached write a small code in the Page_Load function.
protected void Page_Load(object sender, EventArgs e)
{
Thread.Sleep(10000);
Response.Write("This page was generated and cache at:" + DateTime.Now.ToString());
}
Observe that first time the page was loaded it took 10 seconds (because the running thread stopped for 10 seconds), but next time (within 15 seconds) if you refresh the page, it does not take any time.
The OutputCache directive has other parameters to control the behaviour of the output cache. Let us have a look:
Attribute |
Option |
Description |
DiskCacheable |
true/false |
Specifies that output could be written to a disk based cache |
NoStore |
true/false |
Specifies that the “no store” cache control header is sent or not |
CacheProfile |
String name |
Name of a cache profile as to be stored in web.config |
VaryByParam |
None * Param- name |
Semicolon delimited list of string specifies query string values in a GET request or variable in a POST request |
VarByHeader |
* Header names |
Semicolon delimited list of strings specifying headers that might be submitted by a client |
VaryByCustom |
Browser Custom string |
Tells ASP.Net to vary the output cache by browser name and version or by a custom string |
Location |
Any Client Downstream Server None |
Any: page many be cached anywhere Client: cached content remains at browser Downstream: cached content stored in downstream and server both Server: cached content saved only on server None: disables caching |
Duration |
Number |
Number of seconds the page or control is cached |
Let us add a text box and a button to the previous example and add this event handler for the button.
protected void btnmagic_Click(object sender, EventArgs e)
{
Response.Write("<br><br>");
Response.Write(" <h2> Hello, " + this.txtname.Text + "</h2>");
}
And change the OutputCache directive like:
<%@ OutputCache Duration="60" VaryByParam="txtname" %>
If you run the program you will observe how ASP.Net caches the page on the basis of the name in the text box. You can download the project file for the entire example.
Data Caching
This is the most flexible type of caching but requires some code to implement. The basic principle is that you add items that are expensive to create to a special built-in collection object (called cache), which is globally available. Unlike the application object it is thread-safe i.e. you need not lock or unlock the collection before adding or removing an item. Cache items are removed automatically when expired. Items in the cache support dependencies.
You can add an item to the cache by simply by assigning a new key name. Like:
Cache[“key”] = item;
But you can see this does not allow you any control over the amount of time the item will be retained. ASP.Net provides the Insert() method for inserting an object to the cache. This method has four overloaded versions. Let us see the various versions first.
Overload |
Description |
Cache.Insert((key, value); |
Inserts an item into the cache with the key name and value with default priority and expiration |
Cache.Insert(key, value, dependencies); |
Inserts an item into the cache with key, value, default priority, expiration and a CacheDependency name that links to other files or items so that when these change the cache item remains no longer valid |
Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration); |
This indicates an expiration policy along with the above issues. |
Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback); |
This along with the parameters also allows you to set a priority for the cache item and a delegate that, points to a method to be invoked when the item is removed. |
Sliding expiration is used to remove an item from the cache when it is not used for the specified time span. The following code snippet stores and item with a sliding expiration of 10 minutes with no dependencies.
Cache.Insert(“my_item”, obj, null, DateTime.MaxValue, TimeSpan.FromMinutes(10));
Let us try a simple cache test:
Create a page with just a button and a label. Write the following code in the page load event:
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
{
lblinfo.Text += "Page Posted Back.<br/>";
}
else
{
lblinfo.Text += "page Created.<br/>";
}
if (Cache["testitem"] == null)
{
lblinfo.Text += "Creating test item.<br/>";
DateTime testItem = DateTime.Now;
lblinfo.Text += "Storing test item in cache ";
lblinfo.Text += "for 30 seconds.<br/>";
Cache.Insert("testitem", testItem, null, DateTime.Now.AddSeconds(30), TimeSpan.Zero);
}
else
{
lblinfo.Text += "Retrieving test item.<br/>";
DateTime testItem = (DateTime)Cache["testitem"];
lblinfo.Text += "Test item is: " + testItem.ToString();
lblinfo.Text += "<br/>";
}
lblinfo.Text += "<br/>";
}
Run the page and observe it’s behavior.
Conclusion
In this article we have discussed the basic principles behind caching in ASP.Net pages. We have just touched the concepts of Output Caching and Data Caching. Though I am going to say bye for now, your journey begins here. Keeping the above thoughts and ideas in mind, you can start studying the page behavior in Fragment caching and Data Source caching. The topics which need to be checked are: substitution control, Cache profiles, The disk output cache SQL cache dependencies and Custom dependencies. I would like to come back some other day with these topics.
Till then,
Au Revoir.