Andrew Davey has posted an interesting article on composing async operations that doesn"t require a spaghetti-code style state machine. It doesn"t look particularly hardened to exceptions on End* calls, but the technique is interesting, using the monad-like nature of LINQ to compose continuations.
I blogged about something very similar over a year ago, and it looks like it's getting easier to do now.