Synchronization Context in ASP.NET Core

In legacy ASP.NET (pre- ASP. NET Core), the ASP.NET request begins within a context known as the request context (similar to the UI context in a WPF application). Here, the ASP.NET request might initially be handled by any thread pool thread.

Now, consider the scenario where an async method is executed during this request flow. When an 'await' is encountered, the original thread handling the request exits the context and returns to the thread pool. Once the 'await' operation is completed, the continuation needs to resume within the request context again. At any given time, only one thread enters the request context to execute the request. Thus, this continuation will be queued if another thread is serving a different request within that request context. The request will resume once the request context becomes available, potentially on a different thread from the thread pool. To resume the operation again within the request context, certain maintenance activities are required, such as setting the HttpContext.Current, etc. The SynchronizationContext is the concept that helps manage this context switching.

In the case of a UI application, returning to the original context is necessary because only the thread running in the UI context can modify the UI once the async operation is completed. In ASP.NET, this is not necessary unless for example, you depend on HttpContext for some data. You can avoid this behavior of returning to the original context by calling 'ConfigureAwait(false)' on the awaiter that awaits the async task. This allows execution to continue without the need to run within the request context.

In ASP.NET Core, the concept of the synchronization context does not exist. In the above scenario, the continuation would simply run on any thread pool thread without the need to wait in the queue or re-enter the request context. Hence, there is no relevance in calling 'ConfigureAwait(false)'.

However, if you are developing a general-purpose library that doesn't know the context of execution, it is best practice to call 'ConfigureAwait(false)'. The library may be used within a UI application or a legacy ASP.NET application and can benefit from running the continuation code in a contextless manner within the library code.