Await operator and async keyword

The asynchronous method in which await is used must be modified by the async keyword.

The opposite is not always true: you can mark a method as async without using await in its body.

What await actually does is to suspend execution of the code until the awaited task completes; any task can be awaited.

Note: you cannot await for async method which returns nothing (void).

Actually, the word ‘suspends’ is a bit misleading because not only the execution stops, but the thread may become free for executing other operations. Under the hood, await is implemented by a bit of compiler magic: it splits a method into two parts - before and after await. The latter part is executed when the awaited task completes.

If we ignore some important details, the compiler roughly does this for you:

publicasyncTask<TResult>DoIt(){// do something and acquire someTask of type Task<TSomeResult>
varawaitedResult=awaitsomeTask;// ... do something more and produce result of type TResult
returnresult;}

This can be advantageous when you need to execute a long running method on the UI thread without freezing the UI.

But there is a very important remark here: Asynchronous does not always mean concurrent (parallel or even multi-threaded). Even on a single thread, async-await still allows for asynchronous code. For example, see this custom task scheduler. Such a ‘crazy’ task scheduler can simply turn tasks into functions which are called within message loop processing.

We need to ask ourselves: What thread will execute the continuation of our method DoIt_Continuation?

By default the await operator schedules the execution of continuation with the current Synchronization context. It means that by default for WinForms and WPF continuation runs in the UI thread. If, for some reason, you need to change this behavior, use methodTask.ConfigureAwait():