What is the best way to lock cache in asp.net?

Viewed 40481

I know in certain circumstances, such as long running processes, it is important to lock ASP.NET cache in order to avoid subsequent requests by another user for that resource from executing the long process again instead of hitting the cache.

What is the best way in c# to implement cache locking in ASP.NET?

10 Answers

Here's the basic pattern:

  • Check the cache for the value, return if its available
  • If the value is not in the cache, then implement a lock
  • Inside the lock, check the cache again, you might have been blocked
  • Perform the value look up and cache it
  • Release the lock

In code, it looks like this:

private static object ThisLock = new object();

public string GetFoo()
{

  // try to pull from cache here

  lock (ThisLock)
  {
    // cache was empty before we got the lock, check again inside the lock

    // cache is still empty, so retreive the value here

    // store the value in the cache here
  }

  // return the cached value here

}

For completeness a full example would look something like this.

private static object ThisLock = new object();
...
object dataObject = Cache["globalData"];
if( dataObject == null )
{
    lock( ThisLock )
    {
        dataObject = Cache["globalData"];

        if( dataObject == null )
        {
            //Get Data from db
             dataObject = GlobalObj.GetData();
             Cache["globalData"] = dataObject;
        }
    }
}
return dataObject;

I saw one pattern recently called Correct State Bag Access Pattern, which seemed to touch on this.

I modified it a bit to be thread-safe.

http://weblogs.asp.net/craigshoemaker/archive/2008/08/28/asp-net-caching-and-performance.aspx

private static object _listLock = new object();

public List List() {
    string cacheKey = "customers";
    List myList = Cache[cacheKey] as List;
    if(myList == null) {
        lock (_listLock) {
            myList = Cache[cacheKey] as List;
            if (myList == null) {
                myList = DAL.ListCustomers();
                Cache.Insert(cacheKey, mList, null, SiteConfig.CacheDuration, TimeSpan.Zero);
            }
        }
    }
    return myList;
}
Related