Thread Safety in .NET–Difference Between using Monitor.Enter and Monitor.Exit and lock

   When we want to develop ThreadSafe solutions .NET two of the options that we can use are Monitor and lock. But what exactly happens when we use one and another? What are the differences between one and the other?

   Basically the difference is that lock really emits code that places a a Monitor inside a try…finally block. So the real difference is that lock really gives us a exception proof Monitor, since it makes sure that it gets free of that locking even if an exception occurs.

   So lets see a sample of that:

     Imagine this as the code that we write using lock.

   1:              object something = new object();
   2:              lock (something)
   3:              {
   4:                  var query = new TargetProcessEntities()
.Bug.Where(bug => bug.BugID > 100);
   5:   
   6:                  foreach (var bug in query)
   7:                  {
   8:   
   9:                      Console.WriteLine("{0}", bug.BugID);
  10:   
  11:                  }
  12:              }




.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

     The generated code will be: (using .NET Reflector)


   1:          object CS$2$0000;
   2:          object something = new object();
   3:          bool <>s__LockTaken0 = false;
   4:          try
   5:          {
   6:              Monitor.Enter(CS$2$0000 = something, 
ref <>s__LockTaken0);

7: IQueryable<Bug> query = from bug in

new TargetProcessEntities().Bug

   8:                  where bug.BugID >= 100
   9:                  select bug;
  10:              foreach (Bug bug in query)
  11:              {
  12:                  Console.WriteLine("{0}", 
bug.BugID);
  13:              }
  14:          }
  15:          finally
  16:          {
  17:              if (<>s__LockTaken0)
  18:              {
  19:                  Monitor.Exit(CS$2$0000);
  20:              }
  21:          }




.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }







  So as we can see the lock that we placed in the original code at line 2, really gave place to a try…finally block like we can see at lines 4…6 and 14…21.



  Basically when we need to use locks in order to have Thread Safety, than we should use lock instead of Monitor.Enter and Monitor.Exit, since lock really gives us an optimized way to use the Monitor class.



  I’d like to thank Richard Blewett for his great explanation of it.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

* Copy This Password *

* Type Or Paste Password Here *

752 Spam Comments Blocked so far by Spam Free Wordpress

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>