Freigeben über


ASP.Net server side application wide data caching

Thanks to the comment, Peter
I've added additional code that will make it avoid possible race conditions
Mainly I test for null, lock the code and test for null again to make sure that no change in the state was done during the locking process

Here's a problem that I tried to solve for a couple of days:
You have a lot of data on the server and you try to show it to lots of clients. How do you do this trying to have a good performance?

The solution that I found is the subject of this post: You cache the data server side and give it to the clients from the cache. The cache should be application wide so all the clients would use the same one.

Because my data is pretty static I also set the expiry time of the cache to 1 hour.

Here is the code example:

You should create a static or singleton class that would your code would be able to access from anywhere and you pass the HTTPContext to that class when you requets the cached object:

private static object theLock = new object();
<cached_type> GetCached( Cache cache )
{
   <cached_type> cachedObject = cache[<cacheID>] as <cached_type>;
   if( null == cachedObject )
   {
      lock( theLock )
{
if( null == cachedObject )
{
            cachedObject = new <cached_type>();
            cache.Add( <cacheID> , cachedObject , null , DateTime.Now.AddHours( 1 ) , Cache.NoSlidingExpiration , CacheItemPriority.Normal , null );
         }
      }
   }
   return cachedObject;

Every time you call this method it will look up to see if the object is in the cache. If it;s not it will create it and pout it in the cache with a expiration of 1 hour. After one hour the cached object will be expired and the next call will recreate it.

This is useful when you have to deal with showing large data and you don't want to overkill the DB.

Please leave comments if you think this approach is good or bad :)

Thanks,
Ionutz

Comments

  • Anonymous
    September 11, 2006
    If found to be empty, than you should make a lock on a sync object, than retest for null - this would save the competition problems.
  • Anonymous
    September 18, 2006
    Yeah, this one is ok :)
  • Anonymous
    April 07, 2009
    you could check against default(<cached_type>) instead of null to support value types. You could also make a generic method  i.e.: public T GetCacheValue<T>(string cacheId); and do the casting inside the method to return a strong typed object. cheerz