There are a lot of good articles and tutorials about caching out there. Here are some notes I've been saving on the topic...
On a very simple level, there are two methods of caching:
- Output Cache for storing frequently requested pages
- The .NET Cache API for storing arbitrary data
Output Cache
Output caching is extremely fast. However, when using output caching, the code-behind is not re-run for each request. Dynamic data will not be displayed. The server saves a copy of the fully built page (response) and will return that saved copy for each request. You can use parameters to generate a set of cached pages/controls. For example, if you have a querystring parameter with 5 different values, you can set up output caching to save those 5 pre-rendered pages. Output caching is typically declared in the markup.
<%@OutputCache Duration="240" VaryByParam="none" %>
<%@OutputCache Duration="240" VaryByParam="GetOrPostVariableName" %>
.NET Cache API
The Cache API is very versatile and lets you cache data from your code. The typical formula for caching is:
- Get data from cache
- If no data was returned, get the data from the resources (database query, file access, etc.) and store the data in cache
// Check to see if the value is cached
string cachedValue = HttpContext.Current.Cache["CacheKey"] as String;
if (cachedValue != null && cachedValue != string.Empty)
{
// Perform the resource intensive operation
cachedValue = GetValue();
// Insert the value into cache
HttpContext.Current.Cache.Insert("CacheKey", cachedValue, null, DateTime.Now.AddMinutes(240), TimeSpan.Zero);
}
// Use cachedValue
Application object
Another option for caching is to use the Application object, a common trick from “Classic ASP”. However, using the cache API will provide you with more features.
So when do you use cache?
- If data can be used more than once
- If data is general rather than specific to a given request or user
- If the data is user- or request-specific, but is long lived
Why would you want to avoid using cache?
- To prevent out of memory errors.
For performance, you can generally consider there are four basic hardware categories: processor (% utilization), memory (# of bytes to # of available bytes), disk (input/output time), network bandwidth (input/output time). Your servers have finite resources in each of these categories. Caching reduces the dependence on slow resources (disk and network) and increases the dependence on fast resources (memory). Thus, if you use too much caching, your server can run out of memory. Generally on an x86 machine, you want to run a process with no higher than 800MB of private bytes in order to reduce the chance of an out-of-memory error.
What are some advanced caching tips?
- Cache supports expiration dependencies that can force invalidation. These include time, key, file, and database (added in 2.0). You can create custom cache invalidators.
- Dynamically loading output cached controls
- If you use session state in a page that has output caching enabled, and if the application runs on IIS 6.0, then you need to turn off kernel-mode output caching
- Adding an application-wide bypassCache setting that will allow you to easily turn caching off
- Preventing race conditions while loading cache in a high-load application
This code snippet adds bypassCache and race condition checks:
// Check to see if we are using caching and if the value is cached
string cachedValue = HttpContext.Current.Cache["CacheKey"] as String;
if (bypassCache || (cachedValue != null && cachedValue != string.Empty))
{
// Check to see if we are currently caching this item
If (isCachingInProgress)
{
System.Threading.Thread.Sleep(1000);
// Try again
}
else
{
// Perform the resource intensive operation
// (inside this operation, set isCachingInProgress to true when starting and false when finishing)
cachedValue = GetValue();
// Insert the value into cache
HttpContext.Current.Cache.Insert("CacheKey", cachedValue, null, DateTime.Now.AddMinutes(240), TimeSpan.Zero);
}
}
// Use cachedValue
References
ASP.NET Caching
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspnet/html/asp04262001.asp
ASP.NET Caching: Techniques and Best Practices
http://msdn.microsoft.com/asp.net/reference/state/default.aspx?pull=/library/en-us/dnaspp/html/aspnet-cachingtechniquesbestpract.asp
Caching with ASP.NET
http://aspnet.4guysfromrolla.com/articles/022802-1.aspx
10 Tips for Writing High-Performance Web Applications
http://msdn.microsoft.com/msdnmag/issues/05/01/ASPNETPerformance/
Keep Sites Running Smoothly By Avoiding These 10 Common ASP.NET Pitfalls
http://msdn.microsoft.com/msdnmag/issues/06/07/WebAppFollies/
Output Caching – VaryByCustom attribute
http://vertigoblogs/liam/archive/2005/08/03/1290.aspx
Peter A. Bromberg demonstrates that the Application object is a high-performing method of caching. Application vs. Cache Class Speed Tests
http://www.eggheadcafe.com/articles/20030405.asp
Accessing ASP.NET Cache from multiple threads
http://www.dotnet247.com/247reference/msgs/56/283604.aspx