async - stay on the current thread?

If I execute an asynchronous method and it runs, it surely runs on another thread.

No, it typically runs on another thread. It does not surely run on another thread.

Stop thinking about threads for a moment and think about the nature of asynchrony. The nature of asynchrony is:

  • I've got some workflow that I am currently executing.
  • I can't proceed in this workflow until I get information X.
  • I'm going to do something else until I get information X.
  • At some point in the future, once I have X, I'm going to come back to where I left off in my workflow and continue.

Suppose you're doing your taxes and in the middle of this complicated workflow you have a large addition to perform. You can perform a few operations then remember where you are, and go have lunch. Then come back and perform a few more operations, then remember where you are, and feed the cat. Then come back and perform a few more operations, then remember where you are, and wash the dishes. Then finish off the calculations, and resume where you left off in your workflow.

That's an asynchronous calculation but it only needed a single worker to do it. Having multiple workers is just a particularly convenient way to do asynchrony, it is not a requirement.


The async/await support was added to help programmers write GUIs that don't freeze. Particularly useful in Store apps, and the core reason it was added to C# v5, WinRT is a pretty unfriendly api that has many asynchronous methods.

The "stay on the same thread" scenario is very important in a GUI app, required because a GUI isn't thread-safe. It does however require a dispatcher loop (aka Application.Run), the only way to get asynchronous code to resume on the same thread. That loop is the core solution to the producer-consumer problem.

Clearly your program doesn't have one, looks a lot like a console mode app. You therefore don't get this behavior, it resumes on a worker thread.

Not much of a problem, you don't actually need it to resume on the same thread since a console is thread-safe anyway. Well, mostly, not counting the lock that was added in .NET 4.5 when you ask for input. Which of course also means that you don't have a heckofalot of use for async/await either, a Task works fine as well.