0

I've got an ASP.NET WebForms application which has pages using Async=True and I'm using RegisterAsyncTask(new PageAsyncTask(InitialiseAsync)); in my OnLoad method to call business logic asynchronously.

Now I know ASP.NET WebForms requires async calls to be followed with ConfigureAwait(true) as it needs to return back to the original synchronisation context to finish the page. However the async call chain goes down into a library assembly (also built by us). The library doesn't need to know, nor care about sync contexts to do its asynchronous job. Also, it could (potentially) be used in other contexts such as a Console app.

Therefore:

  1. should the library methods always use ConfigureAwait(true) (in case it's being used by a context sensitive application such as ASP.NET Web Forms)?; or
  2. is it okay for the library methods to use ConfigureAwait(false) and for the WebForms app to use ConfigureAwait(true)?; or
  3. (I'm sure this is not the answer but...) should I pass in a boolean value to the library stating whether to use ConfigureAwait(true) or ConfigureAwait(false)?

I've been using option 1 up until now but I'm now suspecting that I should be using option 2 so that the library code can await back onto any thread and the app will eventually context switch back to the required context thread when the call stack comes back out.

Is that right? Thanks

Chris Walsh
  • 3,423
  • 2
  • 42
  • 62
  • 3
    Note that `ConfigureAwait(true)` is the default -- it doesn't need to be specified – canton7 Jan 08 '20 at 16:13
  • Thanks @canton7. I'm aware of that but being explicit is recommended and also gets rid of code lens warnings.. – Chris Walsh Jan 08 '20 at 16:14
  • 2
    @ChrisWalsh it's the other way round. The recommendation is to use `ConfigureAwait(false)` in libraries, thus letting the consumers decide whether they want to return to the original sync context or not. – Panagiotis Kanavos Jan 08 '20 at 16:18
  • Hi @PanagiotisKanavos, I'm actually suggesting that maybe I should use `ConfigureAwait(false)` in the library code (as in option 2). Can you clarify where I've got it the wrong way around in my OP. Thanks. – Chris Walsh Jan 08 '20 at 16:20
  • 1
    Since you are talking about a library, I don't expect these method to call anything in the front end or something that _needs_ to be done on the main thread. So they should use `ConfigureAwait(false)`. When you _use_ these methods in your front end or asp, _you_ await them with `true` and everything is fine. – René Vogt Jan 08 '20 at 16:20
  • Hi @RenéVogt, so no, the library isn't doing any front-end stuff. The library is actually calling web services which have 10-50ms turnaround times so no impact on front end. – Chris Walsh Jan 08 '20 at 16:22
  • Thanks everyone. I think René has clarified the position (that option 2 is safe) i.e. library awaits with `false` and app uses awaits with `true`. Thanks. – Chris Walsh Jan 08 '20 at 16:24
  • 2
    https://devblogs.microsoft.com/dotnet/configureawait-faq/ great blog post, paragraph "When should I use ConfigureAwait(false)?" should help with anwering this question – Piotr L Jan 08 '20 at 16:24

1 Answers1

2

ConfigureAwait is a decision that only needs to be made per function. If a specific function needs to return to its context, then it should not use ConfigureAwait(false); otherwise, it may use it. Whether the functions caller needs a context is immaterial; when its caller awaits, it can decide for itself whether to use ConfigureAwait(false) or not. So option (3) should never be used.

You can go with option (2), and that's the one that I would choose at this time. ConfigureAwait(false) does have some benefits. However, there is currently an ongoing shift in opinion on this matter, largely driven by the fact that ASP.NET Core does not have a context (so ConfigureAwait(false) is a noop, and people don't like it cluttering up their code). For myself, I still use ConfigureAwait(false) in library code, but some other developers have removed ConfigureAwait(false) from their libraries completely. This is equivalent to your option (1). Either of those options would work; if performance isn't a concern, it just comes down to preference.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • Thanks for your informative answer. It adds additional points to the other answers already given. Most appreciated. – Chris Walsh Jan 15 '20 at 15:26