Say, if I have the following block on C# code:
public class SynchedClass
{
public void addData(object v)
{
lock(lockObject)
{
//Shall I worry about catching an exception here?
//Do the work
//arr.Add(v);
}
}
private List<object> arr = new List<object>();
private object lockObject = new object();
}
Shall I attempt to catch exceptions inside the lock
block? (My main concern is that the exception may be raised inside the lock which will prevent the lock from being "unlocked".)
Lock will be released when exception escapes from the lock block.
That is because lock(){...}
is translate by compiler roughly into:
Monitor.Enter(obj);
try{
// contents of the lock block
}finally{
Monitor.Exit(obj);
}
There is more to consider than just releasing the mutex.
An exception occuring within a lock
will release the lock, but what state is the program in now? A thread waiting on the lock will now wake up, and will perhaps now be dealing with invalid state. This is a difficult problem with no ideal solution.
The best thing is to try to keep your locks as small as possible and to call methods that don't throw. (That's ignoring the elephant in the room that is the evil ThreadAbortException
...)
For a good discussion of these issues, see Eric Lippert's article: Locks and exceptions do not mix.
A lock statement of the form "lock (x) ..." where x is an expression of a reference-type, is precisely equivalent to (C# 4.0):
bool entered = false;
try {
System.Threading.Monitor.Enter(x, ref entered);
...
}
finally { if (entered) System.Threading.Monitor.Exit(x); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With