Can Monitor.Enter
throw any exception. I am doing a code review and find that Monitor.Enter
is before try block. Do you see any issues with in?
Monitor.Enter(...)
try
{
...
}
finally
{
Monitor.Exit(..)
}
Can Monitor.Enter
throw any exception. I am doing a code review and find that Monitor.Enter
is before try block. Do you see any issues with in?
Monitor.Enter(...)
try
{
...
}
finally
{
Monitor.Exit(..)
}
Hans Passant's comment is of course correct. If
Monitor.Enter
throws before the lock is taken then you do not want the finally to run. If it throws after the lock is taken and after the try is entered, then the lock is released. (More on this later.) But if the throw happens after the lock is taken but before the try is entered, then the lock will never be cleaned up.This is a rare but possible situation.
In C# 4 we changed the codegen of the lock statement so that the monitor enter is inside the try. This ensures that the lock is always released if something throws after the lock is taken. However, note that this might still be wrong. If something throws after the lock is taken then whatever non-atomic mutation the lock is protecting might be half-completed, and the finally block then unlocks the lock and allows access to the inconsistent state! The fundamental problem here is that you shouldn't be throwing inside a lock in the first place.
See my article about the issue for more discussion.
Monitor.Enter
can throw at least the following exceptionsnull
Enter
has it'sInterrupt
method invoked.If it acquires the lock, then no.
But an exception might be thrown between the
Monitor.Enter
and thetry
block.The recommended method is the new Enter method, new in .NET 4:
This is the correct pattern, whether
Enter()
throws (can throw) or not.Only after the call to
Enter()
succeeds your code is under the responsibility to callExit()
.Suppose the call to
Enter()
fails. Then calling the correspondingExit()
is simply incorrect, it will make matters worse. SoEnter()
has to be outside (before) the try block.