Can the current SynchronizationContext be null?

https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

This is a great article, and I know that all the details cannot be covered, because it essentially involves pasting the source code for the .NET platform. So, quoting the text:

Each thread has a current context. If "Current" is NULL, then the current thread context is "new SynchronizationContext ()", by convention.

On the other hand, however:

By default, the current SynchronizationContext is pending and this SynchronizationContext is used to resume after (more precisely, it captures the current SynchronizationContext if it is not null , in which case it captures the current TaskScheduler)

These two statements are largely contradictory, so I think this is the result of some simplification that was made by the author (I am fine).

Can anyone explain this? The code that can help answer my question (find the syncCtx variable), this piece of code is associated with the second quote.

+5
source share
1 answer

The corresponding code snippet you are looking for is inside the internal Task.SetContinuationForAwait method:

 // First try getting the current synchronization context. // If the current context is really just the base SynchronizationContext type, // which is intended to be equivalent to not having a current SynchronizationContext at all, // then ignore it. This helps with performance by avoiding unnecessary posts and queueing // of work items, but more so it ensures that if code happens to publish the default context // as current, it won't prevent usage of a current task scheduler if there is one. var syncCtx = SynchronizationContext.CurrentNoFlow; if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext)) { tc = new SynchronizationContextAwaitTaskContinuation( syncCtx, continuationAction, flowExecutionContext, ref stackMark); } else { // If there was no SynchronizationContext, then try for the current scheduler. // We only care about it if it not the default. var scheduler = TaskScheduler.InternalCurrent; if (scheduler != null && scheduler != TaskScheduler.Default) { tc = new TaskSchedulerAwaitTaskContinuation( scheduler, continuationAction, flowExecutionContext, ref stackMark); } } 

In fact, he performs two checks, first sees that it is not null , but the second, to make sure that this is not the default SynchronizationContext , which, in my opinion, is the key point here.

If you open a console application and try to extract SynchronizationContext.Current , you will definitely see that it can be null .

 class Program { public static void Main(string[] args) { Console.WriteLine(SynchronizationContext.Current == null ? "NoContext" : "Context!"); } } 
+1
source

Source: https://habr.com/ru/post/1237051/


All Articles