Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么SynchronizationContext检查为空?_C#_Multithreading - Fatal编程技术网

C# 为什么SynchronizationContext检查为空?

C# 为什么SynchronizationContext检查为空?,c#,multithreading,C#,Multithreading,WindowsFormsSynchronizationContext类的,在try块中: SynchronizationContext currentContext = AsyncOperationManager.SynchronizationContext; //Make sure we either have no [....] context //or that we have one of type SynchronizationContext if (currentContext =

WindowsFormsSynchronizationContext类的,在try块中:

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
,这一事实在很大程度上与此无关。诚然,这可能不会改变,因为它是一个公共静态接口,但依赖于它,这是一个完全不必要的依赖关系。您希望您的代码尽可能清楚地表明其意图,而此检查正好做到了这一点,同时也避免了对公共接口的内部行为的直接依赖。

因此,我看到了以下内容(前两位与您的问题相同):

然后转到:

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

            return SynchronizationContext.Current;
        }
这将导致:
在行中(SynchronizationContext.SetSynchronizationContext(newsynchronizationcontext());

但是它会返回同步上下文。当前的

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,但如果给定
??
运算符,这是可能的。

好的,
SynchronizationContext.Current
是每个线程的属性,因此不需要同步,因为其他线程只能设置自己的
SynchronizationContext
。这里的注释是一个无用的完美示例注释。它回显代码已经明确指定的内容。@usr它检查
AsyncOperationManager.SynchronizationContext
(这是第二个代码段)。它的返回值被检查为null,如果它返回
SynchronizationContext.Current
,那么它会检查
SynchronizationContext.Current
是否为null。如果
SynchronizationContext.Current==null
为真,则
SetSynchronizationContext
将分配一个新的同步上下文。它不会是
null返回时。@YuvalItzchakov肯定有可能。我没有讨论
GetMutableExecutionContext()
是否与
GetExecutionContextReader()相同
或否,但根据我在
??
中看到的情况,我认为有可能在
设置SynchronizationContext
之后,它仍然是空的。我个人从未见过
SynchronizationContext
在winforms应用程序中为空(但除非在控制台应用程序中手动设置,否则总是空的)但我认为这可能是一种可能性。看到没有
null
检查
ec
,我假设它不能,否则你会看到
NullReferenceException
ec
是这样的:
Thread.CurrentThread.GetMutableExecutionContext()
而当前的
正在尝试获取
线程.CurrentThread.GetExecutionContextReader()
。这是两个不同的方法调用,我没有检查这两个调用是否在同一事物上运行。我怀疑你是对的,尽管它们是相同的事物(不需要空检查),但我没有深入研究。
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;
    }