async / await, some reasoning
this post will try to make some reasoning about the .NET 4.5 / C#5 await keyword.
I will begin with a quiz.
how long will it take to the following method to produce the 42 value?
you should remember that conceptually the await keyword will translate to a continuation.
the above code can be compare to the following TPL 4 code snippet:
whatever come after the await will be compile into a continuation closure.
therefore the 42 value will be produce after 2 second.
How can we await for multiple task?
there is couple of way for awaiting on multiple tasks, but the most recommended one is to use Task.WhenAll (you can also use Task.WhenAny to continue after the completion of the first task).
do not confuse the Task.WhenAll with Task.WaitAll, WhenAll is a continuation which happens when all the task come to completion, while WaitAll is a blocking API which will block the execution until all tasks will be completed.
the following snippet demonstrate the Task.WhenAll usage.
the 42 value will now produce after 1 second.
it is somewhat equals to the following TPL 4 snippet:
to wrap it up let think how long will it take to the following snippet to produce a value.
the right answer is 10 seconds, each iteration will result in a continuation closure which will wrap the following iterations.
this can be translate to something like the following snippet (TPL 4).
the execute method will create a state machine which will chain task continuation 10 times and then set the value of 42.
the TaskCompletionSource represent semantics of task (TAP – Task Async Pattern).
TaskCompletionSource does not produce any concurrency (doesn’t attached to any thread), it just present a task which can be project result, exception or cancellation.
the OnNext method immediately return a semantic task which will signal as complete at line 22 (the exit term of the recursion).
await present a continuation. each time the code is hitting the await it construct a new continuation closure.