[英]Can the current SynchronizationContext be null?
https://msdn.microsoft.com/en-us/magazine/gg598924.aspx
这是一篇很棒的文章,我知道所有细节都无法涵盖,因为这实际上涉及粘贴.NET框架的源代码。 所以引用文字:
每个线程都有一个当前上下文。 如果“Current”为null,则按照惯例,线程的当前上下文为“new SynchronizationContext()”。
但另一方面:
默认情况下,当前的SynchronizationContext是在await点捕获的,并且此SynchronizationContext用于在await之后恢复(更确切地说,它捕获当前的SynchronizationContext, 除非它为null ,在这种情况下它捕获当前的TaskScheduler)
这两个陈述相互矛盾,所以我认为这是作者做出的一些简化的结果(我很好)。
有人能解释一下吗? 代码可能有助于回答我的问题(查找syncCtx
变量),这段代码与第二个引用相关。
您正在寻找的相关代码段位于内部方法Task.SetContinuationForAwait
:
// First try getting the current synchronization context.
// If the current context is really just the base SynchronizationContext type,
// which is intended to be equivalent to not having a current SynchronizationContext at all,
// then ignore it. This helps with performance by avoiding unnecessary posts and queueing
// of work items, but more so it ensures that if code happens to publish the default context
// as current, it won't prevent usage of a current task scheduler if there is one.
var syncCtx = SynchronizationContext.CurrentNoFlow;
if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext))
{
tc = new SynchronizationContextAwaitTaskContinuation(
syncCtx, continuationAction, flowExecutionContext, ref stackMark);
}
else
{
// If there was no SynchronizationContext, then try for the current scheduler.
// We only care about it if it's not the default.
var scheduler = TaskScheduler.InternalCurrent;
if (scheduler != null && scheduler != TaskScheduler.Default)
{
tc = new TaskSchedulerAwaitTaskContinuation(
scheduler, continuationAction, flowExecutionContext, ref stackMark);
}
}
它实际上做了两次检查,第一次看到它不是null
,第二次确保它不是默认的SynchronizationContext
,我认为这是关键点。
如果您打开一个控制台应用程序并尝试获取SynchronizationContext.Current
,您肯定会看到它可以为null
。
class Program
{
public static void Main(string[] args)
{
Console.WriteLine(SynchronizationContext.Current == null ? "NoContext" :
"Context!");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.