the concept of async \ await
in this post I will survey the new .NET 4.5 / C# 5 concept of async / await.
I will focus on how to understand what is really happens behind the new async / await syntax.
What’s it all about?
the new async / await syntax is using the C# syntactic compiler to generate async operation from code that is looking very much like a synchronous code.
but before we start we should discus the new C# 5 syntax.
the syntax include 2 keywords:
- async – which is only a marker for async method.
- await – indicate a callback boundary.
so how should we understand what was written in the above code?
actually it is a different way to represent a continuation (you can read more about the continuation concept in here).
the above code is somewhat identical to the following TPL 4 code:
the syntactic compiler will translate the code below the await keyword into continuation state machine, which is logically (not technically) identical to the above code.
Point of interest:
you may have been notice that the async method return a Task even though there is no return within the method block.
surveying the TPL 4 code snippet we can understand that the async method will actually return to the caller immediately after the Task.Factory.StartNew start the task and the rest of the code is actually a continuation callback.
what we got back from the async method is a task which represent the async part of the method.
async / await with return value
async / await can represent a continuation of a callback that accept async result.
the above code will logically translate to:
you may have notice that the return value (on the left side of the await) was unwrapped (DateTime instead of Task<DateTime>)
Which thread is running?
normally when the method doesn’t invoke from the UI thread, everything before the await line will run synchronously on the caller thread.
the Task.Run naturally will be schedule on a different thread and everything under the await will be schedule on different thread then the caller thread, it may be the same thread of the Task.Run or any other ThreadPool thread (when there is only single continuation it will probably be the same thread as Task.Run)
Async and UI
whenever the async method invocation is coming from UI thread (or to be more precise from thread under synchronization context) the continuation return back to the synchronization context thread.
this is quit similar to the following TPL code (.NET 4):
or to more legacy code which is using the synchronization context directly:
async / await is aware of the synchronization context of the caller and if any it schedule the await callback on this context.
the syntactic compiler translate the async / await syntax into state machine which handle the continuation flow after parallel operation.
there is much more for that and I will discuss it in future posts.
you can see it performance characteristic on this post.