Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is my understanding of async/await, how it works and its benefits, correct?

I've asserted my understanding of async/await on a couple of occasions, often with some debate as to whether or not I'm correct. I'd really appreciate it if anyone could either confirm or deny my understanding, and clear up any misconceptions so that I don't spread misinformation.

High-Level Understanding

async/await is a way of avoiding callback hell while writing asynchronous code. A thread that is executing an asynchronous method will return to the thread pool when it encounters an await, and will pick up execution once the awaited operation completes.

Low-Level Understanding

The JIT will split an asynchronous methods into discrete parts around await points, allowing re-entry into the method with method's state preserved. Under the covers this involves some sort of state machine.

Relation to Concurrency

async/await does not imply any sort of concurrency. An application written using async/await could be entirely single-threaded while still reaping all the benefits, much the way that node.js does albeit with callbacks. Unlike node.js, .NET is multi-threaded so by having async/await, you get the benefits of non-blocking IO without using callbacks while also having multiple threads of execution.

The Benefits

async/await frees up threads to do other things while waiting for IO to complete. It can also be used in conjunction with the TPL to do CPU bound work on multiple threads, or off the UI thread.

In order to benefit from non-blocking IO, the asynchronous methods need to be built on top of API's that actually take advantage of non-blocking IO which are ultimately provided by the OS.

Misuse

This is the biggest point of contention in my understanding. A lot of people believe that wrapping a blocking operation in a Task and using async/await will bring about a performance increase. By creating an additional thread to handle an operation, returning the original thread to the thread pool, and then resuming the original method after the task completes, all that's occurring are unnecessary context switches while not really freeing up threads to do other work. While this isn't as much a misuse of async/await as it is the TPL, this mindset seems to stem from a misunderstanding of async/await.

like image 376
w.brian Avatar asked Aug 08 '15 23:08

w.brian


People also ask

What is async await and how does it work?

The async keyword turns a method into an async method, which allows you to use the await 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 an async method.

What is one benefit of using async await?

The biggest advantage of using async and await is, it is very simple and the asynchronous method looks very similar to a normal synchronous methods. It does not change programming structure like the old models (APM and EAP) and the resultant asynchronous method look similar to synchronous methods.

What is the benefit of using async?

with async / await , you write less code and your code will be more maintainable than using the previous asynchronous programming methods such as using plain tasks. async / await is the newer replacement to BackgroundWorker , which has been used on windows forms desktop applications.

What async await means?

1. The word “async” before a function means one simple thing: a function always returns a promise. 2. The keyword "await" makes JavaScript wait until that promise settles and returns its result.


1 Answers

That's pretty much correct.

A few notes though:

  • The thread that starts executing an async method is the caller's thread which may, or may not, be a ThreadPool thread.
  • If an await is reached, but the awaitable (usually Task) is already completed the thread will continue executing the rest of the method synchronously.
  • The thread that resumes running the method is usually a ThreadPool thread, but that depends on the SyncrhonizationContext and TaskScheduler.
  • The JIT isn't involved here (not more than usual). The compiler is the one that turns an async method into the state machine. You can see that with this TryRoslyn example.
  • It's true that async-await doesn't necessarily imply concurrency as it could be single threaded. However, it can still be concurrent even with just a single thread by starting and awaiting multiple asynchronous operations at the same time.
  • async-await and the TPL are not completely separate parts. async-await is built on top of the TPL. That's why it's called the Task-based Asynchronous Pattern.
  • While most truly asynchronous operations are I/O, not all are. You also usually delay asynchronously with Task.Delay or use asynchronous synchronization constructs like SemaphoreSlim.WaitAsync.
like image 61
i3arnon Avatar answered Sep 28 '22 08:09

i3arnon