为什么SynchronizationContext检查为null?
在try块中的WindowsFormsSynchronizationContext类的InstallIfNeeded方法 :
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)) { ...
首先,调用AsyncOperationManager.SynchronizationContext
getter,并检查其返回值是否为null。 在这里检查是否需要null?
下面的AsyncOperationManager.SynchronizationContext
代码。 它首先检查当前同步上下文是否为空,如果是,则创建一个新的。 所以这个getter可能永远不会返回null。
public static SynchronizationContext SynchronizationContext { get { if (SynchronizationContext.Current == null) { SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); } return SynchronizationContext.Current; }
在这里检查是否需要null?
我之前的回答忽略了这样一个事实,即SynchronizationContext.Current
实际上是基于线程创建的,而不是跨多个线程创建的(感谢@PerSerAl指出这一点)。 你可以在代码中看到它:
// Get the current SynchronizationContext on the current thread public static SynchronizationContext Current { get { return Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext ?? GetThreadLocalContext(); } }
实际上,这实际上使得null
检查成为冗余,但确实可以避免将来可能发生的任何围绕SynchronizationContext
实现编码的更改。
使用现在的确切代码,你是对的。
但是,请查看代码的意图 。 关键是安装winforms上下文的唯一安全点是没有其他同步上下文时。 这对应于具有null
同步上下文或默认SynchronizationContext
。
在当前确切版本的代码中,同步上下文永远不能为null
的事实在很大程度上是无关紧要的。 没错,这可能不会改变,因为它是一个公共静态接口,但依赖于它是一个完全不必要的依赖。 您希望您的代码尽可能清楚地表明其意图,并且此检查正是这样做 – 同时还避免直接依赖于公共接口的内部行为。
所以这就是我所看到的(前两位与您的问题相同):
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)) {
然后去:
public static SynchronizationContext SynchronizationContext { get { if (SynchronizationContext.Current == null) { SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); } return SynchronizationContext.Current; }
然后导致: in the line (SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
public static void SetSynchronizationContext(SynchronizationContext syncContext) { ExecutionContext ec = Thread.CurrentThread.GetMutableExecutionContext(); ec.SynchronizationContext = syncContext; ec.SynchronizationContextNoFlow = syncContext; }
但后来它返回了SynchronizationContext.Current
public static SynchronizationContext Current { get { return Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext ?? GetThreadLocalContext(); } }
哪个可能最终到此为止。
private static SynchronizationContext GetThreadLocalContext() { SynchronizationContext context = null; #if FEATURE_APPX if (context == null && Environment.IsWinRTSupported) context = GetWinRTContext(); #endif return context; }
如您所见,如果IsWinRTSupported
返回false,则context
可以为null。
基于我所看到的,空检查可能是一个好主意。 我不知道第一个条件Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext
可以返回null但是给出了??
运营商,这是一种可能性。