Could someone please be kind enough to confirm if I have understood the Async await keyword correctly? (Using version 3 of the CTP)
Thus far I have worked out that inserting the await keyword prior to a method call essentially does 2 things, A. It creates an immediate return and B. It creates a "continuation" that is invoked upon the completion of the async method invocation. In any case the continuation is the remainder of the code block for the method.
So what I am wondering is, are these two bits of code technically equivalent, and if so, does this basically mean that the await keyword is identical to creating a ContinueWith Lambda (Ie: it’s basically a compiler shortcut for one)? If not, what are the differences?
bool Success =
await new POP3Connector(
"mail.server.com", txtUsername.Text, txtPassword.Text).Connect();
// At this point the method will return and following code will
// only be invoked when the operation is complete(?)
MessageBox.Show(Success ? "Logged In" : "Wrong password");
VS
(new POP3Connector(
"mail.server.com", txtUsername.Text, txtPassword.Text ).Connect())
.ContinueWith((success) =>
MessageBox.Show(success.Result ? "Logged In" : "Wrong password"));
The general idea is correct – the remainder of the method is made into a continuation of sorts.
The “fast path” blog post has details on how the
async/awaitcompiler transformation works.Differences, off the top of my head:
The
awaitkeyword also makes use of a “scheduling context” concept. The scheduling context isSynchronizationContext.Currentif it exists, falling back onTaskScheduler.Current. The continuation is then run on the scheduling context. So a closer approximation would be to passTaskScheduler.FromCurrentSynchronizationContextintoContinueWith, falling back onTaskScheduler.Currentif necessary.The actual
async/awaitimplementation is based on pattern matching; it uses an “awaitable” pattern that allows other things besides tasks to be awaited. Some examples are the WinRT asynchronous APIs, some special methods such asYield, Rx observables, and special socket awaitables that don’t hit the GC as hard. Tasks are powerful, but they’re not the only awaitables.One more minor nitpicky difference comes to mind: if the awaitable is already completed, then the
asyncmethod does not actually return at that point; it continues synchronously. So it’s kind of like passingTaskContinuationOptions.ExecuteSynchronously, but without the stack-related problems.