What is SyncRoot?

B

Bob Altman

Some classes (in particular, the Hashtable class) expose a SyncRoot
property. The help for that property states (in part):

Derived classes can provide their own synchronized version of the Hashtable
using the SyncRoot property. The synchronizing code must perform operations
on the SyncRoot of the Hashtable, not directly on the Hashtable. This
ensures proper operation of collections that are derived from other objects.
Specifically, it maintains proper synchronization with other threads that
might be simultaneously modifying the Hashtable object.

Is SyncRoot something that only classes derived from Hashtable need to worry
about? Is there some reason why my code that accesses a Hashtable needs to
synchronize with the Hashtable's SyncRoot property rather than with the
Hashtable itself? If so, why?

Is the following code incorrect for some reason?

' Class data
Dim m_hashTable as new HashTable()

Sub Something
SyncLock m_hashTable ' Should be m_hasTable.SyncLock ??????
<Do something>
End SyncLock
End Sub

TIA - Bob
 
G

Greg Young

Sub Something
SyncLock m_hashTable ' Should be m_hasTable.SyncLock ??????
<Do something>
End SyncLock
End Sub

Yes ... you should never lock on the object itself.
 
W

William Stacey [MVP]

It is just an object the class internally uses to sync access to shared
state. Some classes expose that so that your code can also gain exclusive
access for multiple step operations that need to be atomic. MS changed
their thinking on this in 2.0 and do not use SyncRoot anymore, but instead
let the developer decide how to manage exclusiveness (i.e. Queue -vs-
Queue<T>).

--
William Stacey [MVP]

| Some classes (in particular, the Hashtable class) expose a SyncRoot
| property. The help for that property states (in part):
|
| Derived classes can provide their own synchronized version of the
Hashtable
| using the SyncRoot property. The synchronizing code must perform
operations
| on the SyncRoot of the Hashtable, not directly on the Hashtable. This
| ensures proper operation of collections that are derived from other
objects.
| Specifically, it maintains proper synchronization with other threads that
| might be simultaneously modifying the Hashtable object.
|
| Is SyncRoot something that only classes derived from Hashtable need to
worry
| about? Is there some reason why my code that accesses a Hashtable needs
to
| synchronize with the Hashtable's SyncRoot property rather than with the
| Hashtable itself? If so, why?
|
| Is the following code incorrect for some reason?
|
| ' Class data
| Dim m_hashTable as new HashTable()
|
| Sub Something
| SyncLock m_hashTable ' Should be m_hasTable.SyncLock ??????
| <Do something>
| End SyncLock
| End Sub
|
| TIA - Bob
|
|
 
B

Bob Altman

I spent a few minutes looking at Hashtable and SyncRoot using Reflector.
The only references to SyncRoot in the CLR are those used by the
SyncHashtable class (which simply gets a lock on its internal
hashtable.SyncRoot before performing any instance methods).

In general, it's probably not a bad idea for a class to avoid SyncLock(Me).
I guess there is some scenario where this might cause a problem if the
caller already has the same lock (although I can't think of what that
scenario might be). So, if I inherit from Hashtable, it's reasonable to use
the base class SyncRoot for locking.

But if I am operating on an instance of Hashtable, which does not internally
use SyncRoot for anything, I see no reason why I should use
SyncLock(mytable.SyncRoot)
as opposed to
SyncLock(mytable).
 
C

Chris Mullins

Bob Altman said:
In general, it's probably not a bad idea for a class to avoid
SyncLock(Me).

It's important, I feel, for a class to avoid saying, "SyncLock(Me)". Let me
tell you why I think that:

Multi-threaded code is, as we all know, tricky to get right, and even harder
to debug once it's gone wrong.

Many of the deadlocks I've spent time tracking down over the years ended up
being caused by the exact line of code you showed above. If you do this,
there's no good way to debug things - there's nowhere to put a breakpoint
and say, "show me each time the lock is aquired". When this finally does hit
a breakpoint, figuring out who has the lock is very, very, very hard.

When you do grab the lock on "Me", there's also no way to tell if someone
external to you already has the lock. Deadlocks become very hard to detect
and work through. It's much, much easier to debug a deadlock if everyone
goes through a "SyncRoot" property on which a breakpoint, or
Debug.WriteLine, can be placed....
 
S

Steven Cheng[MSFT]

Hi Bob,

As for the "SyncRoot", it originates from the "ICollection" interface.

#ICollection.SyncRoot Property
http://msdn2.microsoft.com/en-us/library/system.collections.icollection.sync
root.aspx

From the document we can get the "SyncRoot" is just a property which
provide abstraction and encapsulation of the concrete Collection(which
implement Icollection)'s internal implementation. Thus, the user do not
need to care what's the underlying collection instance used internally of
that certain Collection and just use the "SyncRoot" property to perform
"locking" (if that Collection class does support synchornous access).

Therefore, as for HashTable, it is simply one of those Collection class
which support synchornous accessing and use the "SyncRoot" property to
expose its own internal collection object( which need to be locked for
synchornous accessing).

And as for your following comments:
===================
But if I am operating on an instance of Hashtable, which does not
internally
use SyncRoot for anything, I see no reason why I should use
SyncLock(mytable.SyncRoot)
as opposed to
SyncLock(mytable).
====================

Yes, if you've created a custom collection class or a derived HashTable
class which does not use the "SyncRoot" property to expose the underlying
collection object(though this is the recommended practice), you do not need
to use "SyncRoot". Surely, if you know which property or objecc is the
underlying collection instance(and it's accessible), you can directly use
"SyncLock" or lock(C#) on that specific instance.

Hope this also helps clarify it some.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
B

Bob Altman

Thanks Steven. I didn't realize that SyncRoot originated in ICollection,
which explains its existence (but doesn't excuse the sloppy documentation).

Per the documentation: Most collection classes in the System.Collections
namespace also implement a Synchronized method, which provides a
synchronized wrapper around the underlying collection. However, derived
classes can provide their own synchronized version of the collection using
the SyncRoot property. The synchronizing code must perform operations on the
SyncRoot property of the collection, not directly on the collection. This
ensures proper operation of collections that are derived from other objects.

I've read the last part of that statement a dozen times, and it's just
gibberish. What the heck does "derived from other objects" mean? What they
really want to tell us is that, by convention, all synchronization (if any)
performed on a class that implements ICollection should be done using the
ICollection.SyncRoot property. Doing so ensures that all locking on the
ICollection uses the same lock object, whether the locking is performed
internally by the class or by an external client.

This really isn't just an academic exercise on my part. I've wasted a lot
of time staring at that little chunk of documentation trying to figure out
what it's really trying to tell me and what the ramifications are of not
using SyncRoot. Is there some way for me to suggest that the MSDN Library
folks fix this documentation using words more or less as I've written them
above?
 
B

Bob Altman

When you do grab the lock on "Me", there's also no way to tell if someone
external to you already has the lock. Deadlocks become very hard to detect
and work through. It's much, much easier to debug a deadlock if everyone
goes through a "SyncRoot" property on which a breakpoint, or
Debug.WriteLine, can be placed....

That's a great idea. Thanks!
 
S

Steven Cheng[MSFT]

Thanks for your reply Bob,

I've reviewed the document about the SyncRoot and the "Synchronized" method
for those certain collection classes. I think your consideration
reasonable, the document may has explained it a bit indirect and not simple
and clear enough. Your understanding on the "SyncRoot" is correct, it is
just a abstract property which help provide a centralized access point for
colleciton users to perform synchchronize operations.

Of course, you're welcome to provide your feedback and comments to our
products or their documentation. You can submit your comments or requests
through the following means:

1. For documentation, you can find the weblink of the certain document
fragment(msdn or SQL BOL or winfx sdk). e.g.

#ICollection.SyncRoot Property
http://msdn2.microsoft.com/en-us/library/system.collections.icollection.sync
root.aspx

at the bottom of each page, you can find the panel to let you input some
comments and rate the document and the documentation team will receive your
feedback.

2. If you have some suggestion or feedback on a certain product, you can
find the feedback center of that products and submit requests(or file a
bug/issue you find on that product), our product engineers will timely
monitor there. Here is the link of Visual Studio and .NET framework
feedback center:

#Visual Studio and .NET Framework Feedback
http://connect.microsoft.com/feedback/default.aspx?SiteID=210

Any of your feedback and comments would be really appreciated.

Please feel free to let me know if there is any other information you
wonder.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top