C# 为什么SynchronizationContext检查为空?
WindowsFormsSynchronizationContext类的,在try块中: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 =
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;
}