6

https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

这是一篇很棒的文章,我知道无法涵盖所有​​细节,因为这基本上涉及粘贴 .NET 框架的源代码。所以引用正文:

每个线程都有一个当前上下文。如果“Current”为空,则按照惯例,线程的当前上下文是“new SynchronizationContext()”。

然而,另一方面:

默认情况下,当前的 SynchronizationContext 是在 await 点捕获的,这个 SynchronizationContext 用于在 await 之后恢复(更准确地说,它捕获当前的 SynchronizationContext 除非它是 null,在这种情况下它捕获当前的 TaskScheduler)

这两个陈述几乎相互矛盾,所以我认为这是作者所做的一些简化的结果(我很好)。

谁能解释一下?可能有助于回答我的问题的代码(查找变量syncCtx),这段代码与第二个引用有关。

4

1 回答 1

1

您要查找的相关代码位于内部方法中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,其次是确保它不是 defaultSynchronizationContext,我认为这是这里的关键点。

如果您打开一个控制台应用程序并尝试获取SynchronizationContext.Current,您肯定会看到它可以null

class Program
{
    public static void Main(string[] args)
    { 
        Console.WriteLine(SynchronizationContext.Current == null ? "NoContext" :
                                                                   "Context!");
    }
}
于 2015-11-29T16:18:45.493 回答