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.

  • Jerrad Anderson

    I remember going through something like this in software construction class. Another way of saying this would be to always use Immutable objects with private members and static methods.

    Though in practice it is difficult you’ll benefit from it later on

  • http://dotnetdebug.net Eran Sandler

    Jerrad, you are correct.

    There is, however, a pattern that repeats itself in .NET that forces you to lock on a non private member. I am talking about the ICollection.SyncRoot property that is used to sync access to a collection.

    It is public and most collections implement it, but the ones that does implement it or classes that implement ICollection indepedantly will have to remember to NOT use this or Me for the implemenetation of the SyncRoot property.

    Like you said, you will benefit from it but its going to be difficult ;-)

  • http://www.sanjaysingh.net Sanjay Singh

    I was wondering if there is any way to enforce this rule so that developers don’t commit this mistake. May be FxCop could be fed something.

  • Ranjit

    I have made a desktop application in vb.net 3.5, when 10 to 12 clients are using same form to save details in inventory page, its showing deadlock error from sql. Is sync lock of .net will help me to resolve this issue ?

  • Resnef Immatong

    I also commited this bug while running a query search from my sql database using a looping method and showing the output by calling the codes that creates a new system.widows.forms.(and the control like label)…once I loaded a record not less than 150 records, the execution is just fine , however, when I repeat it again and again..my computer slows down and it affects the speed of my computer..and there is also a time that the running program where this code resides crashes and will just let itself to unrun without telling me the bug.. I tried using Try…Catch method but it’s not enough I think…Can I use this deadlock code for VB.net win application???? Please help…tnx…I am hoping for a kind response…