45

How does Asynchronous tasks (Async/Await) work in .Net 4.5?

Some sample code:

private async Task<bool> TestFunction()
{
  var x = await DoesSomethingExists();
  var y = await DoesSomethingElseExists();
  return y;
}

Does the second await statement get executed right away or after the first await returns?

1
  • 2
    await's use is less obvious in a sequential situation like this as it "seems" to do nothing, but actually waits until each async operation completes (otherwise they would run in parallel). If you were doing "something else" after var x = you could await x after that processing, but before var y= to get best use of parallel processing. Commented Jan 8, 2014 at 9:55

3 Answers 3

51

await pauses the method until the operation completes. So the second await would get executed after the first await returns.

For more information, see my async / await intro or the official FAQ.

15

It executes after the first await returns. If this thing confuses you, try to play around with breakpoints - they are fully supported by the new async pattern.

Imagine it would look like this:

var x = await GetSomeObjectInstance();
var y = await GetSomeObjectInstance2(x);

There probably would occur a NullReferenceException somewhere, so the first await has to return first. Otherwise, x would be null/undefined or whatever.

13

The methods calls will still occur sequentially just like "regular", non awaited method calls. The purpose of await is that it will return the current thread to the thread pool while the awaited operation runs off and does whatever.

This is particularly useful in high performance environments, say a web server, where a given request is processed on a given thread from the overall thread pool. If we don't await, then the given thread processing the request (and all it's resources) remains "in use" while the db / service call completes. This might take a couple of seconds or more especially for external service calls.

Now in low traffic websites this is not much of an issue but in high traffic sites the cost of all these request threads just sitting around, doing nothing, in an "in-use" state, waiting for other processes like those db /service calls to return can be a resource burden.

We are better off releasing the thread back to the worker pool to allow it do other useful work for some other request.

Once the db / service call completes, we can then interrupt the thread pool and ask for a thread to carry on processing that request from where it left off. At that point the state of the request is reloaded and the method call continues.

So on a per request basis when using await, the request will still take the same amount of time from the users perspective... plus a tiny smidge more for the switching overhead.

But in the aggregate, across all requests for all users, things can seem more performant to all users as the web server (in this case) runs more efficiently with better resource utilization. i.e. it either doesn't have to queue up requests waiting for free threads to process requests because await is returning them or alternatively we don't have to buy more hardware because we are using the same amount of hardware, more efficiently, to obtain higher throughputs.

There is a switching cost to this though so despite what you see in the default templates and in many docs you shouldn't just blindly use await for every single call. It's just a tool and like all tools it has its place. If the switching cost is not less than the cost of just completing your calls synchronously then you shouldn't use await.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.