Stumbled upon this post that talks about making async web requests.
Now simplicity aside, if in real world, all you do is make an async request and wait for it in the very next line, isn't that the same as making a sync call in the first place?
Stumbled upon this post that talks about making async web requests.
Now simplicity aside, if in real world, all you do is make an async request and wait for it in the very next line, isn't that the same as making a sync call in the first place?
No, async + await != sync
, because of continuation
From MSDN 'Asynchronous Programming with Async and Await (C# and Visual Basic)'
Async methods are intended to be non-blocking operations. An await expression in an async method doesn’t block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.
For example async execution will not block UI thread, and Some TextBox.Text
will be updated after download has finished
private async void OnButtonClick()
{
SomeTextBox.Text = await new WebClient().DownloadStringTaskAsync("http://stackoverflow.com/");
}
No it's not the same.
Your async
code block is waiting for the await
call to return to continue, however the rest of your application isn't waiting and can still continue like normal.
In contrast, a synchronous call would make your entire application or thread wait until the code finished executing to continue on with anything else.
Please allow me to clarify things in regards to async/await.
When await is encountered the underlying state machine allows control to be returned immediately. Then, when the awaited call is completed, the underlying state machine allows execution to resume at the line after the awaited call.
Therefore, the async block is not blocked nor is it waiting for the awaited call to finish; Control is returned immediately when the await command is encountered.
The underlying state machine is part of the "magic" behind the use of async/await that is not disused and missed.
I stumbled on this with the same question in mind, yet after reading the responses the question seems to linger, confused by references to "magic under the hood".
From the above-mentioned Asynchronous Programming :
- The
async
keyword turns a method into an async method, which allows you to use theawait
keyword in its body.- When the
await
keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete.await
can only be used inside anasync
method.
Does the context that encounters await
get blocked?
Does the rest of the application block at the await
?
It depends on how your application is written. If it's a series of dependent await
ed tasks launched sequentially in the same context (see: Trying to understand some async/await behavior)
await asyncCall1();
await asyncCall2(); // waits for asyncCall1() to complete
this way each await
would block spawning of the next one.
On the other hand, the same dependent tasks launched in parallel would execute in parallel and the context would only block at the resp. await
:
Task<int> t1 = asyncCall1();
Task<string> t2 = asyncCall2(); // runs in parallel with asyncCall1()
int val = await t1;
string str = await t2; // waits for asyncCall1() to complete
In general, the await
yields execution to the outer context, from where the current context is called. However, if the outer context itself is awaiting for the current, then it's like a sequential await
s in the same context.
So, to reap the async
benefits, one needs to design the application to run several parallel contexts (UI, data-client etc.), then await
in one context yields execution to other contexts, so the whole application would not block on an individual await
.
async + await don't just make an asynchronous call and wait for the result to be delivered, that would indeed be synchronous. That would happen if you created a semaphore, launched a new pthread for example that signals the semaphore when it is finished, and then wait on the semaphore. But async + await as part of the language is different.
What it does is basically creating a new thread to run the "async" task, passes the "await" code to it as a continuation (which is comparable to a "clever" function pointer),and when the task finished, it calls the "await" code. In other languages, like Objective-C or Swift, that's actually how you achieve the same effect. And all that is asynchronous.