Tuesday 23 March 2010

Lock This! (not)

Having witnessed numerous demonstrations of all manner of concurrency gotchas at the recent DevWeek, I thought I would focus on one particular construct that I see quite often, and admittedly have been responsible for introducing in the past.

Joe Duffy, in his otherwise excellent (and extremely thick) book "Concurrent Programming on Windows", advises us to "Use the C# lock and VB SyncLock for all synchronized regions. Following this guidance ensures that locks will be released even in the face of asynchronous thread aborts, leading to fewer deadlocks (statistically speaking)."

There is a problem here, and the problem is that the lock keyword in C# is in league with Satan. It is as evil as the dreaded "On Error Resume Next" in VB. I cannot think of a single case where its use is justified (so if you can, let me know!). Let’s see why. As always the devil is in the detail.

Let’s look at what the lock keyword actually does. Look at the decompiled MSIL (using Reflector):

L_0009: call void [mscorlib]System.Threading.Monitor::Enter(object)
// synchronised code goes in here...

L_0052: leave.s L_005d
L_0054: ldloc.s CS$2$0001
L_0056: call void [mscorlib]System.Threading.Monitor::Exit(object)
L_005b: nop
L_005c: endfinally

So... when you use the lock keyword, or its even more evil mutant twin, [MethodImpl(MethodImplOptions.Synchronized)] - the true dark lord of attributes - what you are actually doing at an IL level is the equivalent of...

Monitor.Enter(syncLock);
try
{
//do something
}
finally
{
Monitor.Exit(syncLock);
}

Would you write code like this yourself? Would you?

Well not really... Calling Monitor.Enter() with no timeout value means the thread will block until the lock becomes available. Why is this bad? Well... blocking threads are the archenemy of concurrency!

As an example, if you are using the built in threadpool, when a thread becomes blocked the threadpool will start a new thread in anticipation of any new work items that come in. Now, what happens if your synchronised code block calls some resource on the network with a 5 minute timeout? "Kaboom!" is the technical term for it. So really whilst appearing as if it's being defensive, its lack of a timeout naturally leads to unreliable code. So much for using lock to help us wrangle threads.

So... if you really really really must block a thread (and you often don't where you think you do)... Please! For the sake of the children... use something more like this...

if (Monitor.TryEnter(syncLock, 1000)
{
try
{
//do something here
}
finally
{
Monitor.Exit(syncLock);
}
}

There's always time for a Timeout :-)

Friday 19 March 2010

:-0:-0:-0:-0:-0:-0:-0:-0:-0:-0:-0:-0

There was a phrase coined here by the original rockstar programmer Jamie Zawinski (JWZ) back in 1997 (ancient history in web terms)!

"Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems."

Given, this rather interesting post, do we now have an infinite number of problems, simultanously?

NerdParade

Just back from DevWeek 2010!

There was the run-of-the-mill-glitziness surrounding the Entity Framework, Silverlight and the AJAX Client Framework, all of which have had some fairly interesting improvements of late. AJAX expecially so. It's now at one" with jQuery! Yay!

Whilst these, mostly demo-based, sessions contained the usual mix of "gosh that's clever" and "oh dear", I feel that the issues surrounding data and binding things to other things in UI are mostly solved problems. The much more interesting topics to me were more around the "high art" end of distributed computing. As the worlds software evolves from a collection of client/server based applications towards a collection of dynamically enlisted services hosted on the web/cloud, problems of identity, security and trust, scalability and parrallelism become more and more important.

I saw a number of presentations which were genuinely facinating. Some fairly high level (on Windows Identity Foundation), some lower (on Multi-Threading). 2 talks on Security by Dominick Baier were very good and Christian Weyers Demonstration of the Azure Service Bus was the highlight for me. Christian certainly understands how to hold an audiences attention, and even got a round of applause for something which could have been seen as quite dry material if delivered by a lesser presenter. Great stuff.

Also, thanks to the very smart Jeff Richter. I now fully understand how the "volatile" keyword in C# works. Thank you Jeff!