I saw the following code, and wanted to use it for a simple activity which may only be executed one at a time, and won't occur frequently (so the chance of occurring twice at a time is very small, but you never know).
So the code:
// class variable
private static object syncRoot = new object();
// in a method:
lock (syncRoot)
{
DoIt();
}
When another thread comes by and wants to execute the code, how long will it wait until the lock is released? Forever, or can you somehow set a timeout?
And second: if the DoIt()
method throws an exception, is the lock still released?
Know the necessary preconditions for deadlock to take place. Always use Monitor vs Lock to avoid deadlocks.
You should take a step back and ask yourself why you are letting an exception from a method have any say over when a
Monitor
youEnter
isExit
ed. If there's even a chance thatDoIt()
might throw an exception (and I would argue that if possible you re-writeDoIt()
so that it DoesNot), then you should have atry/catch
block within the lock() statement so that you can ensure you perform any necessary clean-up.Jason anwser is excellent, here is a way to wrap it making the call simpler.
and then, use it this way:
The lock will wait forever, as Henk said. An exception will still unlock. It is implemented internally with a try-finally block.
As mentioned, a regular lock will wait forever, which is a risk of deadlocks.
The preferred mechanism is (and note the
ref
):This avoids the risk of not releasing the lock in some edge-cases.
The
finally
(which exists in any sensible implementation) ensures the lock is released even in error conditions.A simple
lock(syncRoot)
will wait forever.You can replace it with
Every thread should ensure exception-safe locking.
Note that the standard
lock(syncRoot) {}
is rewritten toMonitor.Enter(syncRoot)
and a try/finally