简体   繁体   English

为什么SynchronizationContext检查为null?

[英]Why is SynchronizationContext checked for null?

InstallIfNeeded method of WindowsFormsSynchronizationContext class, in the try block: 在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))
{
...

So first, AsyncOperationManager.SynchronizationContext getter is called, and its return value is checked for null. 首先,调用AsyncOperationManager.SynchronizationContext getter,并检查其返回值是否为null。 Is checking for null necessary here? 在这里检查是否需要空值?

Code of AsyncOperationManager.SynchronizationContext below. 下面的AsyncOperationManager.SynchronizationContext代码。 It first checks if Current sync context is null, if it is, then a new one is created. 它首先检查当前同步上下文是否为空,如果是,则创建一个新的。 So probably this getter never returns a null. 所以这个getter可能永远不会返回null。

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

Is checking for null necessary here? 在这里检查是否需要空值?

My previous answer neglected the fact that SynchronizationContext.Current will in fact be created on a thread basis, and not across multiple threads (thanks to @PerSerAl for pointing that out). 我之前的回答忽略了这样一个事实,即SynchronizationContext.Current实际上是基于线程创建的,而不是跨多个线程创建的(感谢@PerSerAl指出这一点)。 You can obviously see it in the code: 你可以在代码中看到它:

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

Effectively, this does in-fact make the null check redundant, but does immune itself from any future changes that may happen in the future to code around SynchronizationContext implementation. 实际上,这实际上使得null检查成为冗余,但确实可以避免将来可能发生的任何将在SynchronizationContext实现中编码的更改。

With the exact code as it is right now, you are right. 使用现在的确切代码,你是对的。

However, look at the intent of the code instead. 但是,请查看代码的意图 The point is that the only point where installing the winforms context is safe is when there is no other synchronization context. 关键是安装winforms上下文的唯一安全点是没有其他同步上下文时。 This corresponds to either having a null synchronization context, or the default SynchronizationContext . 这对应于具有null同步上下文或默认SynchronizationContext

The fact that the synchronization context can never be null in current exact version of the code is largely irrelevant. 在当前确切版本的代码中,同步上下文永远不能null这一事实很大程度上是无关紧要的。 True, this will probably not change, since it's a public static interface, but depending on that is a completely unnecessary dependency. 没错,这可能不会改变,因为它是一个公共静态接口,但依赖于它是一个完全不必要的依赖。 You want your code to signal it's intent as clearly as possible, and this check does exactly that - while also avoiding a direct dependency on the internal behaviour of a public interface. 您希望您的代码尽可能清楚地表明其意图,并且此检查正是这样 - 同时还避免直接依赖于公共接口的内部行为。

So here's what I'm seeing (the first two bits are the same as 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)) {

Which then goes to: 然后去:

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()); 然后导致: 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's returning the SynchronizationContext.Current 但后来它返回了SynchronizationContext.Current

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

Which can potentially end up 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. 如您所见,如果IsWinRTSupported返回false,则context可以为null。

Based on what I'm seeing, the null check is probably a good idea. 基于我所看到的,空检查可能是一个好主意。 I don't know if the first condition Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext can return null but given the ?? 我不知道第一个条件是Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext可以返回null但是给出了?? operator, that's a possibility. 运营商,这是一种可能性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么是 SynchronizationContext.Current null? - Why is SynchronizationContext.Current null? 为什么我的Winforms应用程序中的SynchronizationContext.Current为null? - Why is SynchronizationContext.Current null in my Winforms application? 当前的SynchronizationContext可以为null吗? - Can the current SynchronizationContext be null? WindowsService的OnStart方法中SynchronizationContext为null - SynchronizationContext is null in OnStart method of WindowsService 在WPF中使用Unity解析时,SynchronizationContext.Current为null - SynchronizationContext.Current is null on resolving with Unity in WPF Task.Run vs null SynchronizationContext - Task.Run vs null SynchronizationContext 将 SynchronizationContext 设置为 null 而不是使用 ConfigureAwait(false) - Set SynchronizationContext to null instead of using ConfigureAwait(false) 主线程上的SynchronizationContext.Current为null - SynchronizationContext.Current is null on Main thread 为什么控制台应用程序中未捕获默认 SynchronizationContext? - Why the default SynchronizationContext is not captured in a Console App? SynchronizationContext.Current 在主 UI 线程上的 Continuation 中为 null - SynchronizationContext.Current is null in Continuation on the main UI thread
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM