繁体   English   中英

为什么SynchronizationContext检查为null?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM