I maintained a dictionary of ReaderWriterLockSlim objects for resource access:(sample code is ugly here, just makes you understand my purpose)
static ConcurrentDictionary<string, ReaderWriterLockSlim> rwResourceLocks =
new ConcurrentDictionary<string, ReaderWriterLockSlim>();
And use like this:
if (ResourceStore.Exist("resourceID")) {
if (rwResourceLocks["resourceID"] == null) {
/* create a new lock in thread-safe way */
}
rwResourceLocks["resourceID"].EnderReadLock();
var rc = ResourceStore.GetResource("resourceID");
/* further use of rc... */
rwResourceLocks["resourceID"].ExitReadLock();
}
Resources may be added or removed dynamically and their life-cycle is unpredictable (unable to mornitor removal of resource), as amount of resources grows up, size of rwResourceLocks is increasing too which will lead to memory trouble. Is there a way to solve this problem? (Obviously I can't simply call rwResourceLocks.Clear() to do this)
I know it's a bit complicated :(
You could try using a ConditionalWeakTable instead of a ConcurrentDictionary. A ConditionalWeakTable
automatically removes a value from the dictionary when its key has been collected by the Garbage Collector.
ConditionalWeakTable<object, ReaderWriterLockSlim> _locks;
if (ResourceStore.Exists("resourceID")) {
var rc = ResourceStore.GetResource("resourceID");
var lck = _locks.GetValue(rc, () => new ReaderWriterLockSlim());
lck.EnterReadLock();
// Use the resource here
lck.ExitReadLock();
}