BT

Your opinion matters! Please fill in the InfoQ Survey!

Async/Await – Performance Overheads and Other Pitfalls

| by Roopesh Shenoy  Followers on Jul 04, 2013. Estimated reading time: 1 minute |

A note to our readers: As per your request we have developed a set of features that allow you to reduce the noise, while not losing sight of anything that is important. Get email and web notifications by choosing the topics you are interested in.

Async/Await is arguably the most powerful language feature introduced in C# 5. But what pitfalls are to be avoided? And what are the costs associated with these keywords?

The article “Best Practices in Asynchronous Programming” on MSDN highlights following points –

  • Prefer async Task methods over async void methods, except for Event handlers. They have different error handling semantics. Keith Patton of Marker Metro also explains this in detail.
  • Avoid mixing blocking and non-blocking code – it can cause deadlocks, more-complex error handling and unexpected blocking of context threads.
  • Use ConfigureAwait(false) for better performance if the continuation code does not need the original context – it will run the continuation in a threadpool context. This can also be useful for avoiding deadlocks in case you are forced to mix synchronous and asynchronous code. Note that this has slightly different considerations when used on server-side.

Chris Hurley, Software Engineer at RedGate, explains the CPU overhead of async-await and demonstrates the same by profiling a sample piece of code –

  • Calling a method accompanying “async” keyword involves creating a state machine and building a Task to contain the work that goes on within it, getting the execution context and the synchronization context
  • In the shown example, 963 framework methods were run in order to initialize the relatively simple async method in the first call.
  • The context is cached so subsequent calls have much lesser overhead
  • For methods that would synchronously run in a very short timespan (say 1ms), the async overhead actually blocks the calling thread longer. In the example, it is as much as 45 ms before calling thread is unblocked. Even when run in a loop, though the subsequent calls have lesser overhead, the calling thread does not really see any performance benefit.
  • Conclusion – avoid using async/await for very short methods or having await statements within tight loops (instead put the entire loop in an async method)

We’ve already covered some other common Gotchas when using these keywords.

Rate this Article

Adoption Stage
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread
Community comments

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Discuss

Login to InfoQ to interact with what matters most to you.


Recover your password...

Follow

Follow your favorite topics and editors

Quick overview of most important highlights in the industry and on the site.

Like

More signal, less noise

Build your own feed by choosing topics you want to read about and editors you want to hear from.

Notifications

Stay up-to-date

Set up your notifications and don't miss out on content that matters to you

BT