// we are screwed, since we don't have a reference to 'command' any more

thrownewHorribleException("Argh");

}

Note the comment in the EndDoSomething method. Also note that most of the ‘easy’ ways to get around this either break the caller, fail if callback / state are passed as null / are non-unique, introduce race conditions or don’t properly support all of the ways you can complete the async operation (see previous post for more more details).

Pyrrhic Fix

I got it working using using an AsyncWrapper class and a bunch of state-hiding-in-closures. But man it looks like hard work:

I think that’s a pretty major improvement personally. For brevity I won’t post all the implementation code here, but from the AsyncWrapper implementation above and the signature you can pretty much bang it together in a few mins. It’s surprisingly easy when you know what you are aiming for.

Curried Lama

Now actually in my usage I needed something a bit more flash, where the instance of the object that the Begin method was to execute on would be determined ‘late on’, rather than frozen into the constructor. So I ended up with something looking a bit more like this:

var asyncFunc = newAsyncFunc<SomeCommand, int, string>(

c => c.BeginDoSomethingInternal,

c => c.EndDoSomethingInternal,

callback, state);

// Later on...

var command = newSomeCommand();

return asyncFunc.Begin(command);

(The idea is that a series of these can get stored in a chain, and executed one-by-one, with ‘command’ actually replaced by a state machine – i.e. each operation gets to execute against the current state object in the state machine at the that operation executes)

This results in some crazy signatures in the actual AsyncFunc class, the kind that keep Mitch awake at night muttering about the decay of modern computer science:

…which is just more fiddly typing for the user, not the implementer. And it made for some funky currying for overloaded versions of the ctor where you wanted to pass in a ‘flat’ lambda:

_beginInvoke = (i) => (a,c,s) => beginInvoke(i,a,c,s);

Best keep quiet about that I think.

Since this is the async equivalent of Func<TArg,TRet>, you are probably wondering about async version of Action<TArg> and yes there is one of those. And of course, if you want more than one argument (Action<TArg1,TArg2>) you will need yet another implementation. That really sucks, but I can’t see us getting generic-generics any time soon.

I was talking to Joe Albahari about this at TechEd and he suggested that I was attempting to implement Continuations, which wasn’t how I’d been thinking about it but is about right. But I’d need to post about calling a series of these using AsyncActionQueue<TInstance, TArg> to really explain that one.

PS: As it turns out, this looks a fair bit like some of the Task.FromAsync factory methods in .Net 4:

…but I didn’t know that at the time. Yeah, you can chain those too. Grr. It’s just yet another example of why .Net 4 should have come out a year ago so I could be using it on my current project. And don’t even mention covariance to me.