Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Effects of using multiple awaits in the same method?

I have the following method which commits changes to a db (using Entity Framework):

public async Task<int> CommitAsync(Info info)
{
    if (this.Database.Connection.State == ConnectionState.Closed)
        await this.Database.Connection.OpenAsync();

    await SetInfo(info);
    return await base.SaveChangesAsync();
}

Is the above method safe to use as is, or should I:

  1. Avoid using async-await, or
  2. Use ContinueWith
like image 456
Ivan-Mark Debono Avatar asked May 02 '16 07:05

Ivan-Mark Debono


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).

Can we use multiple await?

As far as I understand, in ES7/ES2016 putting multiple await 's in code will work similar to chaining . then() with promises, meaning that they will execute one after the other rather than in parallel. So, for example, we have this code: await someCall(); await anotherCall();

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.

What is the advantage of async await advantages?

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.


2 Answers

It's absolutely fine to have multiple await expressions in the same async method - it would be relatively useless feature otherwise.

Basically, the method will execute synchronously until it reaches the first await where the awaitable involved hasn't already completed. It will then return to the caller, having set up a continuation for the awaitable to execute the rest of the async method. If execution later reaches another await expression where the awaitable hasn't already completed, a continuation is set up on that awaitable, etc.

Each time the method "resumes" from an await, it carries on where it left off, with the same local variables etc. This is achieved by the compiler building a state machine on your behalf.

like image 148
Jon Skeet Avatar answered Nov 09 '22 02:11

Jon Skeet


Your code looks perfect. It gives your caller the opportunity to do something useful at moments you are waiting instead of everyone doing a busy wait until everything is finished.

The nice thing of using async-await instead of using ContinueWith is that your code looks fairly synchronous. It is easy to see in which order the statements will be executed. ContinueWith also lets you specify the order, but it is a bit more difficult to see.

If a thread enters an async procedure it executes the procedure until it meets an await. Instead of waiting until the awaited procedure is finished, control is given back to your caller who can continue performing the next statements until he meets an await, where control is given to his caller etc. Once everyone is awaiting and your OpenAsync is finished the thread continues doing the statements after OpenAsync until it meets another await.

Someone here in stackoverflow (alas lost his name) explained me once the async-await process in a breakfast metaphor.

A very useful introduction, Stephen Cleary about Async-await. Lets you also understand how async-await prevents problems with InvokeRequired

like image 20
Harald Coppoolse Avatar answered Nov 09 '22 03:11

Harald Coppoolse