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