Thursday, September 30, 2010

Synchronization in .NET: ManualResetEvents and Monitors

I recently needed to simultaneously wake an arbitrary number of waiting threads, each waiting on some condition.  My first approach was to have a shared ManualResetEvent, a subclass of EventWaitHandle with the property that "Once it has been signaled, ManualResetEvent remains signaled until it is manually reset. That is, calls to WaitOne return immediately." (MSDN docs.)  [.NET also has AutoResetEvents, but with these only one waiting thread is woken when the event is signalled.]

The idiom I was using was this: I had a global ManualResetEvent called WakeUp; threads waiting on the condition would call WakeUp.WaitOne() (causing them to sleep until...); a thread identifying the waking condition would call WakeUp.Set(); WakeUp.Reset().  My reading of the MSDN documentation is that the call to Set() should wake all waiting threads, while the call to Reset() should reset the event handle for the next wake-up signal.

Tragically, this did not work and my program would randomly flounder.  If I added a delay between the Set() and Reset() calls, the likelihood of floundering reduced, but wasn't eliminated -- and, besides, that is too disgraceful a hack to contemplate for more than a moment.

The right solution was to use a Monitor.  The idiom here is as follows:

For Threads Waiting On Some Condition


Monitor.Enter(SyncObj);
while (!condition) { Monitor.Wait(SyncObj); }
Monitor.Exit(SyncObj);


which can be abbreviated to


lock (SyncObj) {
  while (!condition) { Monitor.Wait(SyncObj); }
}

For Threads Establishing Some Condition


Monitor.Enter(SyncObj);
// Establish condition.
Monitor.PulseAll(SyncObj);
Monitor.Exit(SyncObj);


which can be abbreviated to


lock (SyncObj) {
  // Establish condition.
  Monitor.PulseAll(SyncObj);
}


Peace at last...  (For the curious, in this particular application it would not have been sensible to set up a separate event handle for each condition, which is what one would normally do.)

Wednesday, September 22, 2010

State Machine Compiler

I've just read about SMC, an open source state-machine compiler targetting multiple languages, including C#.  I can see this coming in rather handy.

Monday, September 13, 2010

Trouble with nulls

Following a conversation with a colleague, I have decided to put to paper what I think is wrong with nulls.

Essentially, this: to the compiler, null means "uninitialised".  It is the default value given to references.

As programmers, however, we invariably overload null with other meanings, such as "the empty list", "the empty string", "the unspecified option", and so forth.

This is bad, because I want the tools (compiler, debugger, etc.) to tell me the difference between "I have forgotten to initialise this variable" and "I have put the wrong value in this variable".

As it is, I end up with a bastardised mixture of meanings in my code requiring a lot of checking that would otherwise be redundant.

Maybe code contracts will be able to clean up this mess...

Monday, September 06, 2010

Equality in C#

Here is a good article on the subject.

I wish, I wish, I wish that C# had ditched nulls and default reference equality; that's such a 1960s resource limited way of thinking.  Equality should mean structural equality by default; one should have to explicitly ask for reference equality or nullable types.

Oh well, here's the summary:

  • Implement IEquatable.Equals(T).
    • Remember to check for null and reference equality.
  • Override object.Equals(object).
  • object.Equals(object, object) does what you expect by first testing for nulls and reference equality.
  • Override object.GetHashCode.
  • If you implement == (reference equality by default), also implement !=.
  • Implement the == and != operators for value types to avoid the need for boxing.

Wednesday, September 01, 2010

WPF and XAML

WPF is Windows Presentation Foundation.  It seems like a first class framework to me.

XAML is Microsoft's eXtensible Application Markup Language.  It is a way of describing user interfaces in XML.  It is rich and powerful.

But, why, in the name of all that is holy, is it not composable?!  For the life of me, I cannot understand why a fragment X works as expected in context Y, but not in context Z.  Nor does the documentation I have been wading through (as in, trying to make progress through the Augean stables) been of any help.  The whole of the net is filled with anecdotal solutions to common problems with, so far, not one whit of a general set of principles to help guide one through the quagmire of UI development using XAML.  I am giving serious consideration to not using it on my next project, but rather coding everything up directly in C#.  I would put money on this being vastly more productive.

I have just ordered a book on the subject that sounds as though it will explain things to my satisfaction ("Applications = Code + Markup" by Charles Petzold, who is apparently something of a luminary).  Of course, this being a modern programming book it doubles as a keep-fit device, weighing in at something over 1000 pages.