views:

117

answers:

2

I'm having to store a Data set in cache for X min and when it expires i have it so that the next request will check if the cache exist and then goes and fetches updated data and set the Cache. The issue is that another user will come-in at this time and try to access the object and causing an exception to be thrown. How do i prevent this from occurring?

+2  A: 

You can do this using the lock statement in C#.

You need an object variable that is used as a "lock" so only one thread can access it at a time.

Put the lock around code that updates or retrieves the cache object.

Here is a simple class which demonstrates this:

public class UpdateCache
{
   private static object _myLockObject;

   public static void UpdateCache()
   {
     lock(_myLockObject)
     {
        .. Update cache object
     }
   }

   public static void LoadFromCache(string key)
   {
     lock(_myLockObject)
     {
       .. retrieve data from cache
     }   

   }
}
Russell
+1  A: 

A typical pattern is to encapsulate the cached object in a property. The property getter can then control all access to the cached object.

private static object _locker = new object();

public static DataSet CachedDataSet
{
    get
    {
        if (Cache["DataSetKey"] == null)
        {
            lock (_locker)
            {
                if (Cache["DataSetKey"] == null)
                {
                    Cache["DataSetKey"] = CreateAndFillDataSet();
                }
            }
        }
        return (DataSet) Cache["DataSetKey"];
    }
}
John Saunders
This code won't compile, the getter has no return.
Tim Jarvis
the downvote (not mine) is a bit harsh though, clearly an oversite
Tim Jarvis
Wait shouldn't the private object be static as well?
BlackTea
Also couldn't I do a Cache Callback when the object is removed to auto start populating the cached object or is it better to use the lock method?
BlackTea
+1 for people being un-reasonable, the principle is correct. Let people known whats missing, don't punish them for not having a compiler in a textbox. Don't forget how fast people respond to try and help others that half the time don't bother to post any code.
rick schott
Should be static, should have return. A callback could be performed; whether that makes sense or not depends on how expensive it is to refill the DataSet and how long it takes to do so. But that's just a performance optimization, and I don't pre-optimize.
John Saunders
Reason for static is that there is only one such DataSet per AppDomain - it's application-wide, not instance-specific.
John Saunders