views:

907

answers:

3

In a c# threading app, if I were to lock an object, let us say a queue, and if an exception occurs, will the object stay locked? Here is the pseudo-code:

int ii;
lock(MyQueue)
{
   MyClass LclClass = (MyClass)MyQueue.Dequeue();
   try
   {
      ii = int.parse(LclClass.SomeString);
   }
   catch
   {
     MessageBox.Show("Error parsing string");
   }
}

As I understand it, code after the catch doesn't execute - but I have been wondering if the lock will be freed.

+14  A: 

First; have you considered TryParse?

in li;
if(int.TryParse(LclClass.SomeString, out li)) {
    // li is now assigned
} else {
    // input string is dodgy
}

The lock will be released for 2 reasons; first, lock is essentially:

Monitor.Enter(lockObj);
try {
  // ...
} finally {
    Monitor.Exit(lockObj);
}

Second; you catch and don't re-throw the inner exception, so the lock never actually sees an exception. Of course, you are holding the lock for the duration of a MessageBox, which might be a problem.

So it will be released an all but the most fatal catastrophic unrecoverable exceptions.

Marc Gravell
I am aware of the tryparse, but it is not truly relevant to my question. This was simple code to explain the question - not a true concern regarding the parse. Please replace the parse with *any* code that will force the catch and makes you comfortable.
Khadaji
How about throw new Exception("for illustrative purposes"); ;-p
Marc Gravell
Except if a `TheadAbortException` occurs between the `Monitor.Enter` and `try`: http://blogs.msdn.com/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx
hmemcpy
+2  A: 

Just to add a little to Marc's excellent answer.

Situations like this are the very reason for the existence of the lock keyword. It helps developers make sure the lock is released in the finally block.

If you're forced to use Monitor.Enter/Exit e.g. to support a timeout, you must make sure to place the call to Monitor.Exit in the finally block to ensure proper release of the lock in case of an exception.

Brian Rasmussen
+4  A: 

"A lock statement is compiled to a call to Monitor.Enter, and then a try…finally block. In the finally block, Monitor.Exit is called.

The JIT code generation for both x86 and x64 ensures that a thread abort cannot occur between a Monitor.Enter call and a try block that immediately follows it."

Taken from: This site

GH