Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Awaits in a single method

People also ask

Can you have multiple awaits in one async function?

In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).

How many await we can use in async?

Description. Async functions can contain zero or more await expressions. Await expressions make promise-returning functions behave as though they're synchronous by suspending execution until the returned promise is fulfilled or rejected.

Is async await single threaded?

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.

What is await method?

The await operator suspends evaluation of the enclosing async method until the asynchronous operation represented by its operand completes. When the asynchronous operation completes, the await operator returns the result of the operation, if any.


You can think of await as "pausing" the async method until that operation is complete. As a special case, if the operation is already completed (or is extremely fast), then the await will not "pause" the method; it will continue executing immediately.

So in this case (assuming that WriteStartDocumentAsync is not already completed), await will pause the method and return an uncompleted task to the caller. Note that the Task returned by an async method represents that method; when the method completes, then that Task is completed.

Eventually, WriteStartDocumentAsync will complete, and that will schedule the rest of the async method to continue running. In this case, it'll execute the next part of the method until the next await, when it gets paused again, etc. Eventually, the async method will complete, which will complete the Task that was returned to represent that method.

For more information, I have an async/await intro on my blog.


Stephens answer is of course correct. Here's another way to think about it that might help.

The continuation of a hunk of code is what happens after the code completes. When you hit an await two things happen. First, the current position in the execution becomes the continuation of the awaited task. Second, control leaves the current method and some other code runs. The other code is maybe the continuation of the first call, or maybe is something else entirely, an event handler, say.

But when the call to xmlWriter.WriteStartDocumentAsync() has completed; what happens? Is the current execution interrupted and returned back to SaveAllAsync()?

It is not clear what you mean by the call "completing". WriteStartDocumentAsync starts an asynchronous write, probably on an I/O completion thread, and returns you a Task that represents that asynchronous work. Awaiting that task does two things, like I said. First, the continuation of this task becomes the current position of the code. Second, control leaves the current method and some other code runs. In this case, whatever code called SaveAllAsync runs the continuation of that call.

Now lets suppose that code -- the caller of SaveAllAsync continues to run, and lets suppose further that you are in an application with a UI thread, like a Windows Forms application or a WPF application. Now we have two threads: the UI thread and an IO completion thread. The UI thread is running the caller of SaveAllAsync, which eventually returns, and now the UI thread is just sitting there in a loop handling Windows messages to trigger event handlers.

Eventually the IO completes and the IO completion thread sends a note to the UI thread that says "you can run the continuation of this task now". If the UI thread is busy, that message gets queued up; eventually the UI thread gets to it and invokes the continuation. Control resumes after the first await, and you enter the loop.

Now WriteStartElementAsync is invoked. It again starts some code running that depends on something happening on the IO completion thread (presumably; how it does its work is up to it, but this is a reasonable guess), that returns a Task representing that work, and the UI thread awaits that task. Again, the current position in the execution is signed up as the continuation of that task and control returns to the caller that invoked the first continuation -- namely, the UI thread's event processor. It continues merrily processing messages until one day the IO thread signals it and says that hey, the work you asked for is done on the IO completion thread, please invoke the continuation of this task, and so we go around the loop again...

Make sense?