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?
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 }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With