The Monitor class in .NET is a pure managed implementation of a Critical Section. It is used to synchronize multiple threads’ access to a code block.

C#’s lock statement and VB.NET’s SyncLock statement are actually evaluated into a Try..Finally block that has Monitor.Enter at the start and Monitor.Exit inside the Finally block.

For example:

[C#]
lock(myObject)
{
// Some code requiring synchronization
}

[VB.NET]
SyncLock MyObject
' Some code requiring synchronization
End SyncLock


The actual code produced is:

[C#]
Monitor.Enter(myObject);
try
{
// Some code requiring synchronization
}
finally
{
Monitor.Exit(myObject);
}

[VB.NET]
Monitor.Enter MyObject
Try
' Some code requiring synchronization
Finally
Monitor.Exit MyObject
End Try

There are two major issues that should be considered when using the Monitor class (or C#’s Lock and VB.NET’s SyncLock):

  1. Monitor only works on Reference objects and NOT value types. This means you cannot use an Integer as the object to lock when entering a monitor because it wil be boxed and releaed right away, effectivly not synchronizing the code.
  2. Locking should always be performed on private or internal objects.

There are a great deal of samples floating around that locks the “this” (“Me” in VB.NET) object, which means you are using the current instance as the object that is used for locking.

If this object is a public one and is used or can be used by others (either inside your organization or outside, if you work in an organization to begin with 😉 ), if you lock this instance and that instance is also available to someone else, they might also use it for locking and essentially create a potential deadlock.

So, what should we do about that?

ALWAYS USE PRIVATE OR INTERNAL OBJECTS FOR LOCKS!

The best way to avoid a deadlock is to ALWAYS use private object for locking.

For example:

[C#]
public class LockClass
{
private static object myLock = new Object()
public function void DoIt()
{
lock(myLock)
{
// Some code block that is in
// need of a sync
}
}
}

[VB.NET]
Public Class LockClass
Private Shared MyLock As Object = New Object()

Public Sub DoIt()
SyncLock MyLock
' Some code block that is in
' need of a sync
End SyncLock
End Sub
End Class

Remeber these two guidelines mentioned above and you will save yourself a lot of time trying to find an elusive managed deadlock that is usually hard to reproduce.