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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…