Monthly Archives: January 2009

I’m lucky enough to be learning German, though I’m afraid I’m not very good. When I was in high school I spent hours memorising verben, but now I’ve not got the aptitude or the patience. My tutor gets exasperated because I’ve learned some handy answers to all her questions in the lesson.

Mostly everything seems to take the dative, though I’ve little idea what that means. You can usually fluff gender – when spoken, mein sounds terribly similar to meine. Sometimes she catches me out, but not often.

Homework, however, I can do. German writing is an exercise in thinking like a compiler – for the most part the language is so uniform and regulated that you can solve most problems through a process of pattern matching and unification. Cui Bono, though.

If you’ve done any GUI programming at all, you’ll have come across a pattern like .NET’s System.ComponentModel.ISynchronizeInvoke. The problem it solves is fairly simple, yet only appears in a multi-threaded environment.

There’s one thread (it’s usually the first one created when the application starts, or at least the one that calls the entrypoint) that is responsible for creating and re-drawing UI controls. It handles messages from the Message Pump, and generally ensures that your UI looks as it should. It’s generally called theĀ GUI Thread.

You can see the actions of the UI thread in Visual Studio. Create a Windows Forms project, and have the eventhandler for a new button throw an Exception. Also, create an event handler for the UnhandledException event on System.AppDomain.CurrentDomain, containing the following code:

MessageBox.Show(((Exception)e.ExceptionObject).StackTrace);

Then just run the app and hit the button. You should see the GUI thread being created, along with a marshal from unmanaged to managed code for the button click. Anyway…

There’s a simple rule: you can only update the UI from the GUI thread. The reason for this is simply explained by example: imagine if you were able to add a list item from one thread, whilst you were moving the window, and the window was being re-drawn from another thread. You’d have half-drawn list items all over the screen, and no consistency in your UI.

The rule is simple, but not usually enforced for performance reasons. Luckily, since .NET 2.0, you’ll get a ThreadAccessException (or similar) when you do this when a debugger’s attached. Back in the bad old days of .NET 1/1.1 you’d sometimes get a Big Red Cross where a control should be. Sometimes you wouldn’t. It’d most often occur once you’d been through UAT and you application was in production.

So what’s the solution? You need to marshal to the GUI thread when you’re not on it, update the control, then get back sharpish. Luckily, System.Windows.Forms.Control implements ISynchronizeInvoke, which provides some stuff that’s interesting to us. This is the bit that most people will be familiar with, but for those that aren’t, here’s the summary:

  • bool InvokeRequired { get; } – Gets a value indicating whether the caller must call Invoke when calling an object that implements this interface.
  • Object Invoke(delegate method) – Synchronously executes the delegate on the thread that created this object and marshals the call to the creating thread.

Simply put:

protected void Update()
{
  if(this.InvokeRequired)
  {
    this.Invoke(new MethodInvoker(this.Update));
  }
  else
  {
    textbox1.Text = "foo"; //whatever
  }
}

Yes folks, that’s another nice bit of boilerplate code that you’ve got to put all over your GUI code. Not pretty. But it’s alright, really, because I don’t do that much GUI code – I’m an infreastructure developer. Just kidding – though I did once refer to GUI programming as ‘painting by numbers’, which didn’t go down at all well with some people at work.

Anyhow, long story short: I found this cool thing that lets you use C# 3’s lambdas to describe the work you want to do on the GUI thread.

It’s the Feast of the Epiphany today, so a little more poetry. Then that’s it for this year, promise.

This is the Journey of the Magi by T. S. Eliot. Eliot converted to Christianity in 1927 and published this poem three years later. It’s a description of that arduous journey from the point of view of one of the Magi; we don’t know which one. According to legend the wise men were astrologers and zoroastrians, which was the principle religion in the Levant before Mohamed arrived. Bathasar, Caspar and Melchior represent the three peoples of the world: Africa, Asia and Europe respectively.

“A cold coming we had of it,
Just the worst time of the year
For a journey, and such a long journey:
The was deep and the weather sharp,
The very dead of winter.”
And the camels galled, sore-footed, refractory,
Lying down in the melting snow.
There were times we regretted
The summer palaces on slopes, the terraces,
And the silken girls bringing sherbet.
Then the camel men cursing and grumbling
And running away, and wanting their liquor and women,
And the night-fires gong out, and the lack of shelters,
And the cities hostile and the towns unfriendly
And the villages dirty, and charging high prices.:
A hard time we had of it.
At the end we preferred to travel all night,
Sleeping in snatches,
With the voices singing in our ears, saying
That this was all folly.

Then at dawn we came down to a temperate valley,
Wet, below the snow line, smelling of vegetation;
With a running stream and a water-mill beating the darkness,
And three trees on the low sky,
And an old white horse galloped away in the meadow.
Then we came to a tavern with vine-leaves over the lintel,
Six hands at an open door dicing for pieces of silver,
And feet kicking the empty wine-skins.
But there was no information, and so we continued
And arrived at evening, not a moment too soon
Finding the place; it was (you may say) satisfactory.

All this was a long time ago, I remember,
And I would do it again, but set down
This set down
This: were we lead all that way for
Birth or Death? There was a Birth, certainly,
We had evidence and no doubt. I have seen birth and death,
But had thought they were different; this Birth was
Hard and bitter agony for us, like Death, our death.
We returned to our places, these Kingdoms,
But no longer at ease here, in the old dispensation,
With an alien people clutching their gods.
I should be glad of another death.

- T. S. Eliot