Nuno Filipe Godinho

Tudo sobre .NET e Arquitectura

Recent Posts

Tags

News

Community

Email Notifications

Archives

Thread Safety em .NET – Diferença entre utilizar Monitor.Enter e Monitor.Exit e lock / Thread Safety in .NET–Difference Between using Monitor.Enter and Monitor.Exit and lock (PT/EN)

(PT)

   Quando estamos a desenvolver soluções em .NET e necessitamos de garantir a segurança entre Threads de forma a manter a solução a funcionar de uma forma coerente. Duas das opções que temos são a utilização de Monitor ou lock. Mas o que acontece exactamente quando utilizamos um e ou outro? Qual é a diferença entre eles?

   Básicamente a diferença é que o lock quando compilado emite um código que coloca o Monitor dentro de um bloco de try...finally. Por isso a diferença é que o lock na realidade fornece-nos um Monitor à prova de excepções, pois garante-nos que ainda que exista uma excepção o nosso lock vai ser retirado libertando o objecto.

   Vamos então ver um exemplo:

     Imaginem o seguinte código utilizando o 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:              }
     O código gerado será: (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:          }


  Então o que podemos ver é que o lock que colocamos na linha 2 do código original deu lugar a um bloco try…finally como podemos ver nas linhas 4…6 e 14…21.

  Por isso mesmo quando necessitarmos de utilizar bloquear recursos de forma a garantir a segurança entre threads e a coerência dos resultados da utilização de multi-threading, deveremos utilizar o lock ao invés de Monitor.Enter e Monitor.Exit, uma vez que o lock na realidade nos fornece uma forma optimizada da utilização da classe Monitor.

  Gostaria de agradecer ao Richard Blewett pela sua excelente explicação.

(EN)  

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:              }
     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:          }


  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.

Comments

Luis Abreu said:

I'm not sure I agree with that (use lock instead of Monitor). Why not use the TryEnter method and do some spin wainting? btw, putting the Monitor.Enter *inside* the try/finally block is not really the panacea it looks like. what's the best option: (1) ensure that no deadlock happens or (2) ensure that some mutable entity is only visible when it's in a "valid" state? I'd say that in most cases (1) is the way to go, but not always...

# Julho 18, 2010 12:58

HillaryTYSON29 said:

Make your own life time more simple get the <a href="bestfinance-blog.com/.../credit-loans">credit loans</a> and all you want.

# Agosto 28, 2010 2:49

annotated bibliography writing said:

You really need to write a lot to realize the essence of the essay writing services essays. But when you do not have time, it will be great to buy custom writing services. Then it would be real to save reputation.

# Agosto 29, 2010 9:34

term paper essays said:

I do think that it is not smart to consume time composing the research papers. Lots of people go another way! They don’t accomplish the term paper essays by their own efforts. They buy research paper from the professional research paper writing service.

# Agosto 30, 2010 12:02

do my essay said:

If decide to write the custom term paper, you will have to know that this requires a hard work! Different people fail their pre-written research papers, because they are not professionals! This is sorrowful, but the order an essay service can support these people any time they want.

# Agosto 31, 2010 5:44

essay writing services said:

All people at shool are willing to have the PhD degree and they order the written essays close to this topic from the custom essay service, and very often they need the topics about essay paper.

# Setembro 1, 2010 9:01

already written essays said:

Thank you a lot that you created the superior writing referring to this good topic. But, to see the really good essay writing service, we suppose read a lot just about buy paper.

# Setembro 1, 2010 9:01

customizing essays said:

Result aimed college students trouble about their academic future, so they use a professional buy an essay service, which is essential.

# Setembro 2, 2010 6:05
Leave a Comment

(requerido) 

(requerido) 

(opcional)

 

(requerido) 

If you can't read this number refresh your screen
Enter the numbers above: