Mon, August 31, 2009, 06:27 PM under
dotNET
The most common way to protect resources from concurrent access from multiple threads in .NET is by using the C# lock (or SyncLock in VB) statement.
lock(obj)
{
// only 1 thread executes this at a time
}
Under the covers it generates code that is equivalent to:
Monitor.Enter(obj);
try
{
// only 1 thread executes this at a time
}
finally
{
Monitor.Exit(obj);
}
If you compile the above under Visual Studio 2010 and look at the code generation in your favorite disassembler (e.g. Reflector before it gets a chance to be updated for .NET 4 and hide the detail) you'll find different code generation similar to this:
bool taken = false;
try
{
Monitor.Enter(obj, ref taken);
// only 1 thread executes this at a time
}
finally
{
if (taken)
{
Monitor.Exit(obj);
}
}
The most important thing to note is the introduction of a
new overload for Monitor.Enter (and there is one for
TryEnter too) which are public so you can even use them directly.
Instead of explaining here what problem the new APIs are trying to address (asynchronous exceptions occurring just before the try block and after the call to Monitor.Enter), I defer you to
Joe's old blog post on orphaned locks.
Don't be too surprised if the original Monitor.Enter overloads (without the boolean parameter) become obsolete.