Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use Async/await all the way down

I would like to get some clarification on what is the added benefit of using of Await and Async all the way down.

If my application is calling await Func1() (So no blocking to the UI here). and Func1 is calling await Func2(), but the results from Func2() are important for Func1 to complete it's job, then why would I need to make Func2() awaitable. Func1() execution will take just as long because it's waiting on Func2 to finish. All what the await is doing here is adding the StateMachine overhead.

Am I missing something here?

like image 211
Alaeddin Hussein Avatar asked Apr 22 '15 21:04

Alaeddin Hussein


2 Answers

A better slogan is async all the way up. Because you start with an asynchronous operation and make its caller asynchronous and then the next caller etc.

You should use async-await when you have an inherently asynchronous operation (usually I/O but not necessarily) and you don't want to waste a thread idly waiting for the operation to complete. Choosing an async operation instead of a synchronous one doesn't speed up the operation. It will take the same amount of time (or even more). It just enables that thread to continue executing some other CPU bound work instead of wasting resources.

But to be able to await that operation the method needs to be an async one and the caller needs to await it and so forth and so forth.

So async all the way up enables you to actually make an asynchronous call and release any threads. If it isn't async all the way then some thread is being blocked.

So, this:

async Task FooAsync() {     await Func1();     // do other stuff }  async Task Func1() {     await Func2();     // do other stuff }  async Task Func2() {     await tcpClient.SendAsync();     // do other stuff } 

Is better than this:

void Foo() {     Func1();     // do other stuff }  void Func1() {     Func2().Wait();  // Synchronously blocking a thread.     // do other stuff }  async Task Func2() {     await tcpClient.SendAsync();     // do other stuff } 
like image 60
i3arnon Avatar answered Sep 25 '22 03:09

i3arnon


The major benefit is the fact that awaiting an asynchronous method returns the worker thread to the pool to be used in other calls (web requests to your .NET MVC web app, for example). The asynchronous work is done on an IO completion thread. When the awaited method finishes, another worker thread will collect the results and resume execution. This prevents worker thread pool exhaustion and allows your application to handle more load (CPU, memory, and network throughput depending).

As for "await all the way down", that seems like an issue to me. Typically await is associated to an external resource (DB call, HTTP request, etc.) that your application must wait on. If you await code that doesn't have external IO dependencies, you're creating overhead that isn't needed. It's possible to have multiple awaits in an async method chain, but awaiting some code that itself calls await but has no other external IO dependency is not good and will just add callback/compiler overhead.

like image 30
Haney Avatar answered Sep 24 '22 03:09

Haney