25

I have been using async/await for a while, but delved deeper recently, and read a lot of best practice tips saying to by default always use ConfigureAwait(false) to prevent deadlocks and improve performance.

I just want to make sure I am not missing something when I presume this only applies when the is an actual current SynchronizationContext or TaskScheduler in play, correct?

If I have a Windows service app that is responding to messages/commands/etc. asynchronously, it always just uses the default scheduler = probably the same threadpool thread that the awaitable completed on will execute the continuation, thus no deadlock and no performance difference can be had from using ConfigureAwait(false), correct?

It's not like I can't put it there, but I hate noisey code so much...

Liam
  • 27,717
  • 28
  • 128
  • 190
Martin Sykora
  • 415
  • 5
  • 5
  • 1
    Preferably you should write code that is modular and does not care if it is running in a console, a windows service, a ASP.NET site, or a windowed project (so yes, you should put it in because your code could be run in a situations where it would need it), but sometimes you know it won't be used in those situations (so no, you should not put it in). Its a matter of coding style. – Scott Chamberlain Sep 12 '14 at 22:23
  • It should actually never be used! At most it is just a hack (that clutters your code). Don't use the Wait() method and you will be fine. – maracuja-juice Feb 19 '19 at 19:44
  • (and .Result aswell) – maracuja-juice Feb 19 '19 at 19:50

1 Answers1

19

In general, this is true. When working in a Console or Service scenario, there is no SynchronizationContext installed (by default) so the continueOnCapturedContext option in ConfigureAwait will have no effect, which means you can safely remove it without changing the runtime behavior.

However, there can be exceptions, so I would often suggest writing your code including ConfigureAwait(false) when appropriate anyways.

The main advantages of including this even in a console or service application are:

  1. The code becomes reusable in other applications later. If you choose to reuse this code, you won't have to track down bugs that arise from not including this.
  2. If you happen to install (or use a library that installs) a SynchronizationContext while running, the behavior of your methods won't change.
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 2
    In my opinion you should never use this as it is at best just a hack and clutters your code significantly. "Using ConfigureAwait(false) to avoid deadlock is at best just a hack)" https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – maracuja-juice Feb 19 '19 at 19:33
  • 6
    @maracuja-juice -- you misunderstood the author of that article (Stephen Cleary). What he meant was don't use ConfigureAwait(false) for the sole purpose of avoiding deadlocks in code that blocks. Instead, don't block; avoid deadlocks by using async/await all the way up and down the call stack, including at the root. – rory.ap Mar 29 '19 at 14:50
  • 2
    That's exactly what I understood @rory.ap – maracuja-juice Mar 29 '19 at 15:16
  • 12
    So then your statement "in my opinion you should never use this" is misleading and doesn't represent what you claim you understood about his article. – rory.ap Mar 29 '19 at 15:27