[英]Why is SynchronizationContext checked for 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。 在这里检查是否需要空值?
下面的AsyncOperationManager.SynchronizationContext
代码。 它首先检查当前同步上下文是否为空,如果是,则创建一个新的。 所以这个getter可能永远不会返回null。
public static SynchronizationContext SynchronizationContext
{
get
{
if (SynchronizationContext.Current == null)
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
return SynchronizationContext.Current;
}
在这里检查是否需要空值?
我之前的回答忽略了这样一个事实,即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但是给出了??
运营商,这是一种可能性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.