Why is SynchronizationContext checked for null?

The InstallIfNeeded method of the WindowsFormsSynchronizationContext class in the try block:

SynchronizationContext currentContext = AsyncOperationManager.SynchronizationContext; //Make sure we either have no [....] context //or that we have one of type SynchronizationContext if (currentContext == null || currentContext.GetType() == typeof(SynchronizationContext)) { ... 

So, first AsyncOperationManager.SynchronizationContext getter is AsyncOperationManager.SynchronizationContext , and its return value is checked for null. Is zero checking required here?

The AsyncOperationManager.SynchronizationContext code AsyncOperationManager.SynchronizationContext below. First, it checks if the current synchronization context is null, if it is, a new one is created. Therefore, probably this getter never returns zero.

 public static SynchronizationContext SynchronizationContext { get { if (SynchronizationContext.Current == null) { SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); } return SynchronizationContext.Current; } 
+4
source share
3 answers

Is zero checking required here?

My previous answer neglected the fact that SynchronizationContext.Current would actually be created based on a thread, not multiple threads (thanks to @PerSerAl for pointing this out). Obviously, you can see it in the code:

 // Get the current SynchronizationContext on the current thread public static SynchronizationContext Current { get { return Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext ?? GetThreadLocalContext(); } } 

In fact, this actually makes the null check redundant, but is not immune to any future changes that may occur in the future for the code around the implementation of the SynchronizationContext .

+2
source

With the exact code, as of right now, you're right.

However, look at the intent of the code. The fact is that the only point where setting the winforms context is safe is when there is no other synchronization context. This corresponds to either the presence of a null synchronization context or the default SynchronizationContext .

The fact that the synchronization context can never be null in the current exact version of the code is largely irrelevant. True, this probably will not change, since it is an open static interface, but depending on this, a completely unnecessary dependency. You want your code to communicate intentions as clearly as possible, and this check does just that, and also avoids direct dependence on the internal behavior of the open interface.

+1
source

So here is what I see (the first two bits match your question):

 SynchronizationContext currentContext = AsyncOperationManager.SynchronizationContext; //Make sure we either have no [....] context or that we have one of type SynchronizationContext if (currentContext == null || currentContext.GetType() == typeof(SynchronizationContext)) { 

What then comes:

 public static SynchronizationContext SynchronizationContext { get { if (SynchronizationContext.Current == null) { SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); } return SynchronizationContext.Current; } 

Which then leads to: in the line (SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

 public static void SetSynchronizationContext(SynchronizationContext syncContext) { ExecutionContext ec = Thread.CurrentThread.GetMutableExecutionContext(); ec.SynchronizationContext = syncContext; ec.SynchronizationContextNoFlow = syncContext; } 

But then it returns SynchronizationContext.Current

 public static SynchronizationContext Current { get { return Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext ?? GetThreadLocalContext(); } } 

It could potentially be here.

 private static SynchronizationContext GetThreadLocalContext() { SynchronizationContext context = null; #if FEATURE_APPX if (context == null && Environment.IsWinRTSupported) context = GetWinRTContext(); #endif return context; } 

As you can see, context can be null if IsWinRTSupported returns false.

Based on what I see, a zero check is probably a good idea. I do not know if the first condition of Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext return null, but taking into account the operator ?? , what is possible.

0
source

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


All Articles