Bounded Actions Using Lambda – IDisposable is old and ugly!

In .NET 2, it was all the rage to make hand-crafted, clever IDisposables that let you do a bounded action with clean up. Eg,

void SomeMethod()
{
        using (new SetCursorToWaitEggTimer())
        {
            VerySlowOperation();
        }
}

void VerySlowOperation()
{
    ... etc ...
}

This was kind of cute - you could make sure that, even if an exception was thrown, your clean up (eg, changing cursor back to normal) would occur. Implementing the IDisposable was a bit ugly but consuming it wasn't bad.

Now, with the sexy C# 3 syntax, you can do something similar much more elegantly. Eg,

void SomeMethod()
{
       DoWithWaitEggTimer(VerySlowOperation);
}

void DoWithWaitEggTimer(Action action)
{
    try
    {
        Mouse.OverrideCursor = Cursors.Wait;
        action();
    }
    finally
    {
        Mouse.OverrideCursor = null;
    }
}

If you're feeling like more adventures, you can also start passing these delegates around and injecting them. For example:

class SomeClass
{
    public Action RunSlowCode 
    {
    	get { return runSlowCode ?? new Action(a => a.Invoke()); }
    	set { runSlowCode = value; }
    }
    Action runSlowCode;

    void DoSomethingSlow()
    {
         RunSlowCode(PullDataFromExternalSystem);
    }
}

This approach allows you to inject the delegate for what happens when slow code is run. So you could inject DoWithWaitEggTimer() or something new like DoWithWaitMessageDisplayedToUser(). Similarly, it could be used for unit testing or injecting between layers in your application.


Actions

Information

2 responses to “Bounded Actions Using Lambda – IDisposable is old and ugly!”

27 05 2008
Daniel Cadenas (04:17:29) :

I think you are missing the invocation of the action in DoWithWaitEggTimer

27 05 2008
James (10:13:46) :

You're right, thanks! Fixed now 🙂
James