SO I've been doing a ton of reading lately about the net Async CTP and one thing that keeps coming up are sentences like these: "Asynchrony is not about starting new threads, its about multiplexing work", and "Asynchrony without multithreading is the same idea [as cooperative multitasking]. You do a task for a while, and when it yields control, you do another task for a while on that thread".
I'm trying to understand whether remarks like this are purely (well, mostly) esoteric and academic or whether there is some language construct I'm overlooking that allows the tasks I start via "await" to magically run on the UI thread.
In his blog, Eric Lippert gives this example as a demonstration of how you can have Asyncrhony without multithreading:
async void FrobAll()
{
for(int i = 0; i < 100; ++i)
{
await FrobAsync(i); // somehow get a started task for doing a Frob(i) operation on this thread
}
}
Now, it's the comment that intrigues me here: "...get a started task for doing a Frob(i) operation on this thread".
Just how is this possible? Is this a mostly theoretical remark? The only cases I can see so far where a task appears to not need a separate thread (well, you can't know for sure unless you examine the code) would be something like Task.Delay(), which one can await on without starting another thread. But I consider this a special case, since I didn't write the code for that.
For the average user who wants to offload some of their own long running code from the GUI thread, aren't we talking primarily about doing something like Task.Run to get our work offloaded, and isn't that going to start it in another thread? If so, why all this arm waiving about not confusing asynchorny with multithreading?