SyncLock documentation

A

AMercer

The documentation has many examples that use "SyncLock Me". But the
documentation of the SyncLock Statement under "Programming Practices" says
you should not do this (see the snip below), and I think the cited reason is
pretty weak. What do you think?

SyncLock statement snip:

"The lockobject expression should always evaluate to an object that belongs
exclusively to your class. You should declare a Private object variable to
protect data belonging to the current instance, or a Private Shared object
variable to protect data common to all instances.

You should not use the Me keyword to provide a lock object for instance
data. If code external to your class has a reference to an instance of your
class, it could use that reference as a lock object for a SyncLock block
completely different from yours, protecting different data. In this way, your
class and the other class could block each other from executing their
unrelated SyncLock blocks. Similarly locking on a string can be problematic
since any other code in the process using the same string will share the same
lock."
 
T

Tom Shelton

The documentation has many examples that use "SyncLock Me".  But the
documentation of the SyncLock Statement under "Programming Practices" says
you should not do this (see the snip below), and I think the cited reason is
pretty weak.  What do you think?

SyncLock statement snip:

"The lockobject expression should always evaluate to an object that belongs
exclusively to your class. You should declare a Private object variable to
protect data belonging to the current instance, or a Private Shared object
variable to protect data common to all instances.

You should not use the Me keyword to provide a lock object for instance
data. If code external to your class has a reference to an instance of your
class, it could use that reference as a lock object for a SyncLock block
completely different from yours, protecting different data. In this way, your
class and the other class could block each other from executing their
unrelated SyncLock blocks. Similarly locking on a string can be problematic
since any other code in the process using the same string will share the same
lock."

What do you find weak about it? For example, if you have 2 unrealted
methods - using different data, and you use SyncLock Me in both
methods, then two threads calling these methods may needlessly lock
each other.... Strings have the same issue, since they are interned.
 
A

AMercer

What do you find weak about it? For example, if you have 2 unrealted
methods - using different data, and you use SyncLock Me in both
methods, then two threads calling these methods may needlessly lock
each other.... Strings have the same issue, since they are interned.

It seems to be defensive programming carried to extremes. Either the
consumer is SyncLock'ing with good and correct intentions, in which case all
is well, or he has made a poor choice of an object to SyncLock with, in which
case it is his problem, and it is wrong headed (imo) to protect him from his
follies this way. The worst that can happen is that locks are held longer
than they need to be - a deadly embrace is not in the offing.

I don't know - it just seems like someone at MS wrote the snip in a fit of
pique having his sensibilities offended by all the code examples that use
'SyncLock Me'. Do you disapprove of 'SyncLock Me'?
 
B

Bob Altman

"The lockobject expression should always evaluate to an object that belongs
exclusively to your class. You should declare a Private object variable to
protect data belonging to the current instance, or a Private Shared object
variable to protect data common to all instances.

You should not use the Me keyword to provide a lock object for instance
data.

It's a data encapsulation thing. If you use a private variable for your lock
object then you guarantee that callers won't be able to conflict with your lock.
But if you use a public object (your own class reference, for example) then code
outside of your class could cause your code to behave incorrectly.

And it's actually worse that "if", because most code that wants to create a
protected section locks on the object variable that is being protected. In
other words, I would typically write:

' Class data
Private m_yourClass As New YourClass

Sub X()
SyncLock m_yourClass
Do something with m_yourClass
End SyncLock

If your class uses Me as the lock object then you are using the same object that
I used, but for a completely different purpose.

Bob
 
A

AMercer

Bob Altman said:
It's a data encapsulation thing. If you use a private variable for your lock
object then you guarantee that callers won't be able to conflict with your lock.
But if you use a public object (your own class reference, for example) then code
outside of your class could cause your code to behave incorrectly.

And it's actually worse that "if", because most code that wants to create a
protected section locks on the object variable that is being protected. In
other words, I would typically write:

' Class data
Private m_yourClass As New YourClass

Sub X()
SyncLock m_yourClass
Do something with m_yourClass
End SyncLock

If your class uses Me as the lock object then you are using the same object that
I used, but for a completely different purpose.

Bob

In the example below, bbb uses 'synclock me', and ccc uses 'synclock sss'
where sss is an object created only for this purpose, as the documentation
suggests. I realize that sss is not exposed to the customer, but the
customer has a reference to the class, and that I refer to as Me. This is
the situation that I'm interested in, and I don't see any way that synclock
me causes things to "behave incorrectly". All I see is the potential for a
lock to be held longer than necessary. Other than this, bbb and ccc achieve
the same result. In a nutshell, I guess all that I am objecting to is the
existence of "Private sss As New Object" whose sole purpose is the SyncLock
statements in the class's methods.

Same question for you as for Tom Shelton - do you disapprove of 'Synclock Me'?

Public Class aaa

Public Sub bbb()
SyncLock Me
' stuff
End SyncLock
End Sub

Private sss As New Object

Public Sub ccc()
SyncLock sss
' stuff
End SyncLock
End Sub

End Class
 
A

AMercer

Your point about '2 unrelated methods' is well taken. But, lets assume that
there are only 2 methods in the class, and they both mess with all the class
data. See the thread that follows Bob Altman's response.
 
T

Tom Shelton

I almost always create a synchronization object simply because it's easier
for me to remember what it's for.  However, I have one applications that
synclocks on a global string that is computed during application startup.
Again, using this string is the "logical" thing since it's the path to an
executable and I have to wait for some time for the application to get going
before allowing another thread to enter that section of code and starting
another instance of the application.  Multiple instances are allowed to run,
I just don't want to start multiple instances too close together.

As for why the documentation in VB says not to use "synclock me", I have no
idea, especially since I have seen documentation references to using "lock
this" in C#, which is the equivalent.

Mike Ober.- Hide quoted text -

- Show quoted text -

And is usually discouraged...
 
T

Tom Shelton

Your point about '2 unrelated methods' is well taken.  But, lets assume that
there are only 2 methods in the class, and they both mess with all the class
data.  See the thread that follows Bob Altman's response.

Bob's answer is also correct. So, I would still use a internal lock
object - even if every method messed with all of the class level data.
 
G

Guest

I don't know - it just seems like someone at MS wrote the snip in a
fit of pique having his sensibilities offended by all the code
examples that use 'SyncLock Me'. Do you disapprove of 'SyncLock Me'?

Synclock Me can result in unneeded locks on an object.
 
J

Jack Jackson

In the example below, bbb uses 'synclock me', and ccc uses 'synclock sss'
where sss is an object created only for this purpose, as the documentation
suggests. I realize that sss is not exposed to the customer, but the
customer has a reference to the class, and that I refer to as Me. This is
the situation that I'm interested in, and I don't see any way that synclock
me causes things to "behave incorrectly". All I see is the potential for a
lock to be held longer than necessary. Other than this, bbb and ccc achieve
the same result. In a nutshell, I guess all that I am objecting to is the
existence of "Private sss As New Object" whose sole purpose is the SyncLock
statements in the class's methods.

Same question for you as for Tom Shelton - do you disapprove of 'Synclock Me'?

Public Class aaa

Public Sub bbb()
SyncLock Me
' stuff
End SyncLock
End Sub

Private sss As New Object

Public Sub ccc()
SyncLock sss
' stuff
End SyncLock
End Sub

End Class

What does SyncLock do if the same thread tries to lock something that
is already locked?

Your example exposes this possiblility:

Dim a As New aaa

SyncLock a
a.bbb()
End SyncLock

Even if that works, allowing external code to lock the object that is
used internally for locking makes me uncomfortable.
 

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