Question about the use of SyncLock

Question 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

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