Understand ASP.NET facts regarding cache and expiration times, including sliding expiration and process recycling. We need a balance between memory usage and performance. We want improve caching, knowing that large caches can hamper performance, because complex interactions in ASP.NET might result in pages being expired much sooner.
ASP.NET applications are continually recycled. ASP.NET on IIS 7.0 uses a special process model, which greatly enhances the reliability of the programs you are running. IIS 7.0 feels resources are scarce, which means it will unload your web site at any time it feels like it.
| When this occurs | The ASP.NET server might |
| Web site is not accessed for X seconds | Stop the process |
| Web site worker process doesn't check in |
Stop it Decide the process has hung |
| Process doesn't shut down fast enough | Stop it |
| Any time interval has passed |
Stop it To maintain good health |
| Too much memory is used |
Stop it Recycle the process to free memory |
| Too many requests have been handled | Stop it |
You may use a singleton or static class to store a lot of data in your ASP.NET web application or site. This can enhance performance, but it can also lead the server to restart your application more often, thus increasing the amount of work. More caching can lead to lower performance.
| Cache size | Information |
| Large | ASP.NET will decide your process is using too much memory and will restart it, thus invalidating all your caches |
| Small or medium | Your process will use less memory and ASP.NET will let it keep going longer. |
You want a balance between too much caching and too little caching. In this article I am dealing with a mostly static site, which can be built from database queries or just plain aspx pages--it essentially is just an information site, like most of the Internet.
Here is an example and explanation of sliding caching. I feel this to be the best solution for this type of site. The following code is a static class, which means it doesn't need to save state. You can add it to App_Code and call it from anywhere.
// Static method to make output cache with sliding easier to use.
public static class CacheHelper
{
const int _seconds = 600;
public static void CacheThis(HttpResponse response)
{
// Only cache for X seconds. This should reduce the risk of sending
// Googlebot an old page, I guess.
// Use the DateTime class for times.
response.Cache.SetExpires(DateTime.Now.AddSeconds(_seconds));
response.Cache.SetMaxAge(new TimeSpan(0, 0, _seconds));
response.Cache.SetCacheability(HttpCacheability.Public);
response.Cache.SetValidUntilExpires(true);
// Sliding expiration means we reset the X seconds after each request.
// This will likely hugely increase cache lifetime.
// SetETag is required to work around one aspect of sliding expiration.
response.Cache.SetSlidingExpiration(true);
response.Cache.SetETagFromFileDependencies();
}
}
// In your page's code-behind, use the above static method like this.
protected void Page_Load(object sender, EventArgs e)
{
CacheHelper.CacheThis(Response);
}
This paragraph assumes a cache time of 10 minutes. If someone visits at 0 seconds, the page will be generated. Then, if someone else visits after 9 minutes have passed, it will be served from the cache, and the expiration time will be reset. The page will then expire from the output cache after 19 minutes.
There is an intricate cache behavior of ASP.NET on a shared host like many sites use. Memory pressure, and recycling all play a part and obviously putting too many things in the cache will hurt performance. This happens primarily because ASP.NET will get antsy and restart the process more often.
Your site needs to work with ASP.NET's process model, and not against it. You are not in full control with your ASP.NET application--Microsoft has its own plans and does maintenance on your web site for you any time it wants.