views:

257

answers:

2

I have a Dictionary that tracks objects (ClientObject). Both the dictionary and ClientObject's are accessed by multiple threads. When I modify or read any object in this dictionary, I obtain a read or write lock on the dictionary using ReaderWriterLockSlim (rwl_clients) then obtain an exclusive lock on the actual object.

I just wanted to know if I am using these .net threading facilities correctly

Example:

rwl_clients.EnterReadLock();
ClientObject clobj;
if(!m_clients.TryGetValue(key, out clobj))
    return;
rwl_clients.ExitReadLock();

SomeMethod(clobj);

SomeMethod(ClientObject clobj) would do something like:

lock(clobj) {

/// Read / Write operations on clobj

}

Does getting and locking a value (ClientObject) from the dictionary in one thread mean that other threads will respect that lock? In other words, does .net see a value in the dictionary as a single resource (and not a copy) and will therefore respect a lock on that resource in all threads?

One more question, when removing a resource from the dictionary - should I lock it before performing Remove()

Example:

rwl_clients.EnterWriteLock();
ClientObject clobj;
if(m_clients.TryGetValue(key, out clobj)) {
     lock(clobj) {
          m_clients.Remove(key);
     }
}
rwl_clients.ExitWriteLock();

I have learned so much from this site and appreciate any responses! Thanks.

+2  A: 

Does getting and locking a value (ClientObject) from the dictionary in one thread mean that other threads will respect that lock? In other words, does .net see a value in the dictionary as a single resource (and not a copy) and will therefore respect a lock on that resource in all threads?

It depends on the type - if a reference type then yes, if a value type no. This is also why you should never, ever lock on a value type since the value type will be boxed and any subsequent attempts to lock on that value will actually acquire a lock on a different object.

One more question, when removing a resource from the dictionary - should I lock it before performing Remove()

Yes, you should lock before any operation that mutates the state of the object.

As a side note - are you sure that this setup is the best possible solution to your problem? Mutable objects shared across threads tend to create more problems then they solve.

Andrew Hare
Thanks for the response! This really cleared things up for me :)
Ramsey
+1  A: 

If you are adding or removing items from the dictionary, lock the dictionary.

When you put an object in the dictionary, you are putting a REFERENCE to that object in the dictionary. To prevent that object from being changed by a second thread while the first thread is in the process of changing it, lock the object, not the dictionary.

Corey Trager
Only if it is a reference type - the OP's approach will not work for value types.
Andrew Hare
I should be fine if my dictionary is locked with ReaderWriterLockSlim and the items are reference type
Ramsey