IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Entering an Avalon UI Context

Friday 9 April, 2004, 12:06 PM

Jason Olson has just posted an article showing how Avalon's multithreading handling improves on the way Windows Forms works. It's a good summary of the issues, but he misses out my favourite feature.

As you may already be aware, I'm a fan of code that generates try ... finally blocks automatically for locking constructs. However, Jason shows an example which uses an explicit try ... finally block to ensure that the UI context he acquires gets released. His code is more or less of this form:

private void UpdateUIFromWorkerThread()
{
    try
    {
        this.Context.Enter();
        // Do stuff to UI now that we've got the context
        ...
    }
    finally
    {
        this.Context.Exit();
    }
}

This is all very well, but I'd prefer to use less code - I want things to look as elegant as they do when using the lock keyword in C#. Fortunately, Avalon supports exactly the same trick I used in my blog showing what to do if you like the lock style of syntax, but need to use timeouts when acquiring locks. Avalon's UIContext provides a function called Access(), which enters the UIContext and returns a temporary object that implements IDisposable. This temporary object calls Exit() for you when you Dispose() it. This means that you can take advantage of the C# using construct to generate the relevant try and finally blocks, with a generated call to Dispose() (and therefore, indirectly, Exit()) inside the implicit finally block. This means your code can be much simpler:

private void UpdateUIFromWorkerThread()
{
    using (this.Context.Access())
    {
        // Do stuff to UI now that we've got the context
        ...
    }
}

This code will Exit() the context when the flow leaves the using block. No need to clutter your code with explicit finally blocks.

Interestingly, the current build (4051 - the PDC version) gives Access() a return type of IDisposable, so they're not using the optimization that Eric Gunnerson pointed out for my solution: if you return a struct as the helper object that calls Dispose(), you can avoid a heap allocation. But making the return type returning IDisposable effectively prevents this optimization - if you do return a struct, the CLR has to box it onto the heap, negating the purpose of the optimization. Maybe they'll change this in a future release of Longhorn. (Although maybe not - using a specific struct as a return type means there's another type to document, making the API appear to be more complex to the user. So perhaps the user education issues mean the optimization isn't worth it here.)

The only fly in the ointment is that, as the documentation says, this uses an infinite timeout when entering the context. As I said in my previous blog, I think that's a risky thing to do. So what I would really like to see is some kind of way of specifying a timeout so that a deadlock will cause an error to be thrown (eventually) rather than locking up my application for ever.

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk