Synclock With An Arbitrary Private Variable

B

Bob Day

Ok, I have done a lot of reading(of the newsgroup answers, help files and
MSDN articles) of synclock.

I understand what you are saying in the newsgroup, and it is very helpful.
It does, however, directly contradict what the VS 2003 help file says, and
it seems that various posters to my original questions on Synclock disagree
with each other. It seems, that the best practice is to use sysnlock to
protect code, not variables. That generates further questions.

Consider: Sub1 locks a section of code, not the global_variable (this is, I
think, the best practice on how it should be done). Sub 2 locks the global
variable. Now consider sub1A. If Sub1 and Sub1A are called by different
threads, it would seem to be that the value of Global_Varialbe would be
unpredictable, because while the code is locked in each sub, the varialbe it
not, so two different threads could change it at the exact same moment. Now
conisder 2B, since the variablle is locked, the results would be
predictable. Two threads could not modify the Global_Varialbe at the same
time (one would proceed the other).

Your thoughts? Thanks!

Bob Day
Private Sub1

' create an arbitrary variable to lock a section of code

Dim Lock1 as new object

Synclock(Lock1)

Global_Varialbe = Local_Variable + 1

End Synclock

end sub1

Private Sub1A

' different code, but ultimatly also modifys Global_Variable

' create an arbitrary variable to lock a section of code

Dim Lock1 as new object

Synclock(Lock1)

Global_Varialbe = Local_Variable + 1

End Synclock

end sub1A

Private Sub2

' lock the variable itself

Synclock(Global_Variable)

Global_Variable =Local_Variable + 1

End Synclock

End sub2

Private Sub2A

' different code, but ultimatly also modifys Global_Variable

' lock the variable

Synclock(Global_Variable)

Global_Variable =Local_Varialbe + 1

End Synclock

End sub2A
 
P

Peter Huang

Hi Bob,

Your idea is correct basically except you must use reference type. (i.e.
Global_Variable must be a reference type in your Sub2 and Sub2A.

The type of the expression in a SyncLock statement must be a reference
type.

SyncLock Statement
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbls7/html/
vblrfvbspec8_5.asp

As the MSDN said,
The SyncLock block is implicitly contained by a Try statement whose Finally
block calls the Shared method System.Monitor.Exit on the expression

Use Monitor to lock objects (that is, reference types), not value types.
When you pass a value type variable to Enter, it is boxed as an object. If
you pass the same variable to Enter again, it is boxed as a separate
object, and the thread does not block. The code that Monitor is supposedly
protecting is not protected. Furthermore, when you pass the variable to
Exit, still another separate object is created. Because the object passed
to Exit is different from the object passed to Enter, Monitor throws
System.SynchronizationLockException. For details, see the conceptual topic
Monitor.

For detailed information, please take a look at the link below.

Monitor.Enter Method [Visual Basic]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemthreadingmonitorclassentertopic.asp

If you have any concern on this issue, please post here.

Regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jay B. Harlow [MVP - Outlook]

Bob,
As Peter stated, your lock needs to be reference types, I'm adding it needs
to be outside of your subroutines!

Sub1 & Sub1A will not work as the lock is private to the subroutines. For a
lock to be effective two threads need access to it.

Sub2 & Sub2A seems non-sense to me as you are changing the lock itself, As
soon as Sub2 modified Global_Variable itself (not the object), as long as
Sub2A is not waiting on the old Global_Variable it would be able to enter
its block of code, as the new Global_Variable is not locked by Sub2 (the old
Global_Variable is the one that is locked).

I would recommend (as I have attempted before) to use a lock OUTSIDE your
subroutines, that is also distinct from the object you are protecting.

Something like:

Private Readonly Global_Lock As New Object()
Private Global_Variable As Integer
Private Sub3
' create an arbitrary variable to lock a section of code
Synclock(Global_Lock)
Global_Variable= Local_Variable + 1
End Synclock
end

Private Sub3A
' different code, but ultimatly also modifys Global_Variable
' create an arbitrary variable to lock a section of code
Synclock(Global_Lock)
Global_Variable= Local_Variable + 1
End Synclock
end

Notice that Sub3 & Sub3A are using a common lock Global_Lock, when Sub3 has
Global_Lock locked it is able to modify the "shared resource" of
Global_Variable, Sub3A is not able to enter its block of code as Sub3
currently owns Global_Lock, when Sub3 reaches its End Synclock, Sub3A will
be able to enter its Synclock block and use Global_Variable.

Hope this helps
Jay
 

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