Question about the use of SyncLockQuestion about the use of SyncLock
Old forum URL: forums.lhotka.net/forums/t/5740.aspx
JoeFallon1 posted on Wednesday, November 05, 2008
I was looking at the code in:
Public Module MethodCaller
Private _methodCache As Dictionary(Of MethodCacheKey, DynamicMethodHandle) = New Dictionary(Of MethodCacheKey, DynamicMethodHandle)()
Private Function GetCachedMethod(ByVal obj As Object, ByVal info As MethodInfo, ByVal ParamArray parameters() As Object) As DynamicMethodHandle
Dim key = New MethodCacheKey(obj.GetType().FullName, info.Name, GetParameterTypes(parameters))
Dim mh As DynamicMethodHandle = Nothing
If (Not _methodCache.TryGetValue(key, mh)) Then
SyncLock _methodCache
If (Not _methodCache.TryGetValue(key, mh)) Then
mh = New DynamicMethodHandle(info, parameters)
_methodCache.Add(key, mh)
End If
End SyncLock
End If
Return mh
End Function
When I looked in the VS Help I read this:ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/dv_vbalr/html/14501703-298f-4d43-b139-c4b6366af176.htm
Rules
-
Branching. You cannot branch into a SyncLock block from outside the block.
-
Lock Object Value. The value of lockobject cannot be Nothing. You must create the lock object before you use it in a SyncLock statement.
You cannot change the value of lockobject while executing a SyncLock block. The mechanism requires that the lock object remain unchanged.
It looks like the code above is using _methodCache as the lock object in violation of the Rule above. The function modifies _methodCache by adding data to it.
1. Is there a problem?
2. Why not use something simple like this as the lock object? (Remove Shared if placed in the Module.)
Private Shared lockObject As Object = New Object
Joe
vdhant replied on Wednesday, November 05, 2008
"You cannot change the value of lockobject while executing a SyncLock block. The mechanism requires that the lock object remain unchanged."
I could be wrong but i always though that this rule applied to code outside of the locks scope.
"Why not use something simple like this as the lock object? (Remove Shared if placed in the Module.)"
It would mean that anywhere else that _MethodCache is called directly (there may be no where else, but i can't check at the moment) would have to do something with lockObject to see if a lock was present before it could continue. Where as if the lock is on _MethodCache directly the code will naturally hold until the lock is released.
This was my understanding of this type of code works, i could be mistaken.
Cheers
Anthony
JonStonecash replied on Wednesday, November 05, 2008
The rule for the locking object is that there must be an object (meaning a reference type) and that you cannot change the object that is the locking object. The key concept here is that it is the object identity that is important. In this case, the identity object (the collection) is not changing, merely the contents. The locking is using that identity and really does not care about the contents. No problem here.
There is nothing wrong with using an object whose only reason for existing is to be used as a lock. And there is nothing wrong with using another object that has a stable identity that is also being used for something else. I have not measured it, but I would guess that the shared multi-tasked object would be a slight bit more efficient: no separate object to create, no memory to hold it. My preference would be to use a separate object but I have no problem with the way this is coded.
Jon Stonecash
Copyright (c) Marimer LLC