There is some overhead in thread management, yes. But in a server scenario (e.g. a web api) there is already thread management happening, as it all runs in threads from a thread pool.
I don't believe that you pay a significant additional cost per await - i.e. if you have one await in your code, then you might as well use as many as you can to chop the operation up into small parts so that operations can flow through better.
If you "must wait for a thread to become available" for any significant amount of time then you have run out of threads despite being async, and you have other problems.
in UI code, there is a guideline that "operations that could take over 50ms should be async" (1) so as to not lock the UI thread. But it's clear that this does not apply to web server code where it's all thread pool threads already.
I don't believe that you pay a significant additional cost per await - i.e. if you have one await in your code, then you might as well use as many as you can to chop the operation up into small parts so that operations can flow through better.
If you "must wait for a thread to become available" for any significant amount of time then you have run out of threads despite being async, and you have other problems.
This article talks about the mechanics of how the operation's completion bubbles back up to your code, in some detail: http://blog.stephencleary.com/2013/11/there-is-no-thread.htm...
See also, avoiding some basic mistakes: http://www.anthonysteele.co.uk/AsyncBasicMistakes
in UI code, there is a guideline that "operations that could take over 50ms should be async" (1) so as to not lock the UI thread. But it's clear that this does not apply to web server code where it's all thread pool threads already.
1) http://blog.stephencleary.com/2013/04/ui-guidelines-for-asyn...