Update: It is acceptable if this method is not thread safe, but I\'m interested in learning how I would make it thread safe. Also, I do not want to lock on
I would go with the pragmatic approach and use the dummy variable.
If this is not possible for whatever reason, I would use a Dictionary
with key
as the key and a dummy object as the value and lock on that value, because strings are not suitable for locking:
private object _syncRoot = new Object();
private Dictionary _syncRoots = new Dictionary();
public static T CheckCache(string key, Func fn, DateTime expires)
{
object keySyncRoot;
lock(_syncRoot)
{
if(!_syncRoots.TryGetValue(key, out keySyncRoot))
{
keySyncRoot = new object();
_syncRoots[key] = keySyncRoot;
}
}
lock(keySyncRoot)
{
object cache = HttpContext.Current.Cache.Get(key);
if (cache == null)
{
T result = fn();
HttpContext.Current.Cache.Insert(key, result, null, expires,
Cache.NoSlidingExpiration);
return result;
}
else
return (T)cache;
}
}
However, in most cases this is overkill and unnecessary micro optimization.