Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Practical usage of await on the same line as the async call?

What's the purpose of calling an async method with await on the same line? (not what is the behavior, but what are the practical uses of this pattern). As far as I understand, this will in effect be a synchronous "blocking" call, as execution in this context will not continue until GetDocumentAsync completes, correct?

Document someDocument = await db.GetDocumentAsync(documentId);
//AFAIK blocks until GetdocumentAsync completes and returns 
CalledAfterAwaitReturnsAndResultIsAvailable(someDocument.SomeProperty);

Most tutorials showing how to call an async method I've seen do this, and I've seen it in other's code. To me it defeats the purpose of asynchronous execution. It would seem like to benefit from the async call, you would make the async call, without the await, and do some other unrelated sequential work(or start some other async calls) not dependent on someDocument, and then do the await to get the result of the async call and then do whatever depended on that return. Such that your other unrelated processing can be performed while the async call is also working in another thread. I've seen the above pattern so much, I am beginning to wonder if I am misunderstanding something.

What is the practical application of making an async call in this way, such that it blocks until it completes?

like image 772
AaronLS Avatar asked Jan 21 '14 19:01

AaronLS


People also ask

What is the difference between await and async async?

Async/Await makes it easier to write promises. The keyword ‘async’ before a function makes the function return a promise, always. And the keyword await is used inside async functions, which makes the program wait until the Promise resolves.

How to call Multiple async/await functions sequential in Python?

Calling multiple async/await functions sequential is same as call a async function with await keyword. To do this, let’s make some changes on run_processes functions so it can call all functions sequential but will results same output.

Can you use await in a non-async function?

If we try to use await in a non-async function, there would be a syntax error: function f() { let promise = Promise.resolve(1); let result = await promise; // Syntax error } We may get this error if we forget to put async before a function. As stated earlier, await only works inside an async function.

What is the use of async in C++?

It allows a program to run a function without freezing the entire program. This is done using the Async/Await keyword. Async/Await makes it easier to write promises. The keyword ‘async’ before a function makes the function return a promise, always.


3 Answers

The await keyword does not call Wait on the task, it calls ContinueWith. The result is that rather than a blocking call, you get a completion callback.

like image 182
Ben Voigt Avatar answered Nov 15 '22 20:11

Ben Voigt


I think the key thing you are missing is that when you hit the first await, the function you were inside returns with a Task<Document> (assuming your function was declared like public async Task<Document> Foo()) and lets the person who called your function continue on doing other work.

The caller can then either process some other work and check on the Task later to see if it is done or he can await immediately himself and continue the deferred work up the chain till you hit someone who does have work to do (on Forms or WPF this goes all the way up to the Message Pump and lets the UI keep responding while you are waiting for the task to finish).

like image 45
Scott Chamberlain Avatar answered Nov 15 '22 22:11

Scott Chamberlain


The practical application of this pattern is when you want to trickle up/expose the async capability to other potential callers of your method. While within the context of your method it will appear to behave as if it is synchronous, it is not actually blocking. A parent caller can benefit from the child methods async capability and perform parallel processing while GetDocumentAsync processes.

public async Task<List<string>> ProcessDocument()
{
  Document someDocument = await db.GetDocumentAsync(documentId);
  //Since await is on the same line as the async call, 
  //  Parse will not be called until GetDocumentAsync completes and result is available.
  //Thus it appears to "block", it is not technically blocking, 
  //  as a caller of ProcessDocument can start an async call to ProcessDocument 
  //  and perform other parallel processing while GetDocumentAsync is processing,
  //  because ProcessDocument is marked async
  return Parse(someDocument.Contents);
}

public async void ApplicationStart() {

    //no await when calling async method, processing begins asynchrounously
    Task<List<string>> parseDocTask = ProcessDocument();

    //we will continue other work while ProcessDocument is asynchronously performing work
    //We can execute DoIndependentWork while at the same time ProcessDocument is working on a separate thread asynchronously
    DoIndependentWork();

    //get result of async call, either will block until result is available,
    // or if async ProcessDocument task has already completed, will continue immediately
    List<string> parsedDocument = await parseDocTask;

    //do something with parsedDocument
}
like image 23
AaronLS Avatar answered Nov 15 '22 20:11

AaronLS