Monitor vs lock
A lock statement is equivalent to:
Monitor.Enter(object);
try
{
// Your code here...
}
finally
{
Monitor.Exit(object);
}
However, keep in mind that Monitor can also Wait() and Pulse(), which are often useful in complex multithreading situations.
Update
However in C# 4 its implemented differently:
bool lockWasTaken = false;
var temp = obj;
try
{
Monitor.Enter(temp, ref lockWasTaken);
//your code
}
finally
{
if (lockWasTaken)
Monitor.Exit(temp);
}
Thanx to CodeInChaos for comments and links
Monitor
is more flexible. My favorite use case of using monitor is when you don't want to wait for your turn and just skip:
//already executing? forget it, lets move on
if(Monitor.TryEnter(_lockObject))
{
//do stuff;
Monitor.Exit(_lockObject);
}
Eric Lippert talks about this in his blog: Locks and exceptions do not mix
The equivalent code differs between C# 4.0 and earlier versions.
In C# 4.0 it is:
bool lockWasTaken = false;
var temp = obj;
try
{
Monitor.Enter(temp, ref lockWasTaken);
{ body }
}
finally
{
if (lockWasTaken) Monitor.Exit(temp);
}
It relies on Monitor.Enter
atomically setting the flag when the lock is taken.
And earlier it was:
var temp = obj;
Monitor.Enter(temp);
try
{
body
}
finally
{
Monitor.Exit(temp);
}
This relies on no exception being thrown between Monitor.Enter
and the try
. I think in debug code this condition was violated because the compiler inserted a NOP between them and thus made thread abortion between those possible.
lock
is just shortcut for Monitor.Enter
with try
+ finally
and Monitor.Exit
. Use lock statement whenever it is enough - if you need something like TryEnter, you will have to use Monitor.