ExecuteAsync takes a *synchronous* delegate (and runs the whole thing on a worker thread).

Maybe there also needs to be a signature that takes an asynchronous delegate and runs it on the the current thread?
But running async on a worker thread was completing the await prematurely on the current thread.