I’m using Enterprise Lib 5.0 caching app block and I’m trying to figure out the best way to handle read/writes in a multi threaded scenario.
Is taking a lock on write and not taking a lock on read the recommended approach?
Update(string key, object value)
{
lock(syncLock)
{
cacheManager.Add(key,value);
}
}
object Read(string key)
{
object o = cacheManager.GetData(key);
return o;
}
//OR is the following Read recommended using a lock
object Read(string key)
{
lock(syncLock)
{
object o = cacheManager.GetData(key);
return o;
}
}
My concern is that if one thread is about to update the item for a specific key at the same time as another thread is about to read the item for the same key.Can this cause races?
Would it make sense to have a dictionary of “keys” to “ReaderWriterLockSlim”s so that you would essentially take a lock for only a specifc key as opposed to a “common” lock in a multi threaded scenario like a web app:
Basically something like this:
Dictionary<string,ReaderWriterLockSlim> dict = new Dictionary<string,ReaderWriterLockSlim> ();
void Update(string key, object value)
{
dict[key].EnterWriteLock();
cacheManager.Add(key,value);
dict[key].ExitWriteLock();
}
object Read(string key)
{
dict[key].EnterReadLock();
object o = cacheManager.GetData(key);
dict[key].ExitReadLock();
return o;
}
You shouldn’t have to do your own locking with The Caching Application Block because “you are assured that the block performs in a thread-safe manner”.
If you take a look at the source code for
Cacheyou will see that theAdd,Remove, andGetDatamethods all obtain locks on the in-memory cache before performing any operations.