The lock statement is translated by C# 3.0 to the following:
var temp = obj;
Monitor.Enter(temp);
try
{
// body
}
finally
{
Monitor.Exit(temp);
}
In C# 4.0 this has changed and it is now generated as follows:
bool lockWasTaken = false;
var temp = obj;
try
{
Monitor.Enter(temp, ref lockWasTaken);
// body
}
finally
{
if (lockWasTaken)
{
Monitor.Exit(temp);
}
}
You can find more info about what Monitor.Enter does here. To quote MSDN:
Use
Enterto acquire the Monitor on the object passed as the parameter. If another thread has executed anEnteron the object but has not yet executed the correspondingExit, the current thread will block until the other thread releases the object. It is legal for the same thread to invokeEntermore than once without it blocking; however, an equal number ofExitcalls must be invoked before other threads waiting on the object will unblock.
The Monitor.Enter method will wait infinitely; it will not time out.