c# – Why do you need a synchronization context on the backend?

Question:

As I understand it, the use of the synchronization context is that it can allow the continuation to be performed on the UI thread (otherwise we will not be able to update the UI, and if we try, there will be an exception).

1. Is the understanding correct?

I've tried doing the example in a .NET Core 2.2 console app. Created an await with a continuous asynchronous operation, the continuation will use the same context as before await. Given the reasons for the existence of the context that I know, I assume that the flow should be the same as before await. But the output to the console was showing the wrong thread ID on the sequel as it was before await.

As I understand it, due to the fact that here (.NET Core console) there is no synchronization context at all during execution. Indeed, there is no UI right there, what is the use of it. I suppose that it will work as I thought only on UI projects such as UWP and WPF.

But here :

I heard that there is no need to use ConfigureAwait (false) in .NET Core. Is it so?

there is information that the .NET Framework has its own context in non-UI projects + custom synchronization contexts can be created in core projects.

2. Why in general can it be useful to create / use context outside of UI projects?

3. Why does the .NET Framework have a sync context by default?

  1. I'm not sure if I understood correctly the arguments in favor of using ConfigureAwait (false) on the .NET Core backend. Did I understand correctly that there could be a sense here only if : (1) I highlighted a part of the logic that I use on the backend, in the lib and reuse it in the UI project. (2) I am afraid of third-party ones who can bring their own context and somehow put on main project. Although why such libs are needed on the back is also a question. ?

Answer:

Old ASP.NET has many globally accessible objects, the main one being HttpContext.Current . By the way, ASP.NET Core has the IHttpContextAccessor interface for the same purposes, but it is not used so widely: now it is quite possible to write a complex web application without ever using this interface – while earlier, directly or indirectly, HttpContext.Current was always used and on any request.

Initially, HttpContext.Current was just a ThreadStatic field, but when ASP.NET began to add asynchrony, it turned out that the values ​​of ThreadStatic fields are "lost" after the execution of asynchronous operations. But if IHttpContextAccessor solves this problem using the AsyncLocal mechanism, then the creators of ASP.NET could not do that, because ASP.NET is older than this mechanism. This is where they came up with the idea of ​​using a synchronization context.

Basically, the main point of using SynchronizationContext in ASP.NET is to restore the HttpContext.Current after the asynchronous operation completes.

At the same time, the synchronization context solves the following tasks:

  1. serialization of continuations – all asynchronous continuations are queued to avoid possible races when accessing shared objects – in the new ASP.NET Core this task was assigned to the programmer and partially to the await operator;

  2. accounting for asynchronous operations, so that you know when the processing of a request has finished – in the new ASP.NET Core, tasks (Task and ValueTask) are used instead.

PS link to sync context implementation – https://referencesource.microsoft.com/#system.web/AspNetSynchronizationContext.cs

Scroll to Top