简体   繁体   English

当前的SynchronizationContext可以为null吗?

[英]Can the current SynchronizationContext be null?

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

It's a great article, and I'm aware that all details could not be covered because that would essentially involve pasting the source code of .NET framework. 这是一篇很棒的文章,我知道所有细节都无法涵盖,因为这实际上涉及粘贴.NET框架的源代码。 So quoting the text: 所以引用文字:

Each thread has a current context. 每个线程都有一个当前上下文。 If "Current" is null, then the thread's current context is "new SynchronizationContext()", by convention. 如果“Current”为null,则按照惯例,线程的当前上下文为“new SynchronizationContext()”。

On the other hand, however: 但另一方面:

By default, the current SynchronizationContext is captured at an await point, and this SynchronizationContext is used to resume after the await (more precisely, it captures the current SynchronizationContext unless it is null , in which case it captures the current TaskScheduler) 默认情况下,当前的SynchronizationContext是在await点捕获的,并且此SynchronizationContext用于在await之后恢复(更确切地说,它捕获当前的SynchronizationContext, 除非它为null ,在这种情况下它捕获当前的TaskScheduler)

These two statements pretty much contradict each other, so I'm thinking this is the result of some simplification that has been made by the author (I'm fine with it). 这两个陈述相互矛盾,所以我认为这是作者做出的一些简化的结果(我很好)。

Could anyone explain this? 有人能解释一下吗? Code that might help in answering my question (look for syncCtx variable), this piece of code is related to the second quote. 代码可能有助于回答我的问题(查找syncCtx变量),这段代码与第二个引用相关。

The relevant piece of code you're looking for is inside the internal method Task.SetContinuationForAwait : 您正在寻找的相关代码段位于内部方法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);
    }
}

It actually does two checks, first to see that it isn't null , and the second to make sure it isn't the default SynchronizationContext , which I think is the key point here. 它实际上做了两次检查,第一次看到它不是null ,第二次确保它不是默认的SynchronizationContext ,我认为这是关键点。

If you open up a Console Application and try to fetch the SynchronizationContext.Current , you'll definitely see that it can be null . 如果您打开一个控制台应用程序并尝试获取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.

相关问题 为什么是 SynchronizationContext.Current null? - Why is SynchronizationContext.Current null? 在WPF中使用Unity解析时,SynchronizationContext.Current为null - SynchronizationContext.Current is null on resolving with Unity in WPF 主线程上的SynchronizationContext.Current为null - SynchronizationContext.Current is null on Main thread 当SynchronizationContext.Current为null时,我可以安全地使用Task.Wait吗? - Can I safely use Task.Wait when SynchronizationContext.Current is null? 主线程的SynchronizationContext.Current如何在Windows窗体应用程序中变为空? - How can SynchronizationContext.Current of the main thread become null in a Windows Forms application? SynchronizationContext.Current 在主 UI 线程上的 Continuation 中为 null - SynchronizationContext.Current is null in Continuation on the main UI thread 为什么我的Winforms应用程序中的SynchronizationContext.Current为null? - Why is SynchronizationContext.Current null in my Winforms application? 解决.NET 4.0中SynchronizationContext.Current为空的问题 - Workaround for issue in .NET 4.0 where SynchronizationContext.Current is null 如何抑制ExecutionContext捕获当前的SynchronizationContext? - How can I suppress ExecutionContext capturing the current SynchronizationContext? 等待不使用当前的SynchronizationContext - await not using current SynchronizationContext
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM