c# - 当前的 SynchronizationContext 可以为 null 吗?

标签 c# multithreading synchronizationcontext

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

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

Each thread has a current context. If "Current" is null, then the thread's current context is "new SynchronizationContext()", by convention.

然而,另一方面:

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)

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

谁能解释一下? Code这可能有助于回答我的问题(寻找 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!");
    }
}

关于c# - 当前的 SynchronizationContext 可以为 null 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33984697/

相关文章:

c# - Async-Await 在预期死锁的地方没有死锁

c# - 动态创建 C# 类的实例

c# - 我如何将 "Thread.Join"设置为 BackgroundWorker?

c# - 显示对话框后启动时任务卡住 UI

c# - BackgroundWorker 进程需要引发要在主 (UI) 线程上处理的自定义事件

multithreading - 并发: Processes vs Threads

c# - Windows 10 UAP 应用程序上的 Google 登录错误

c# - 忽略 MySqlDataAdapter.Update(DataTable) 中的 DATETIME 字段?

c# - 这如何不导致堆栈溢出?

java - 如何从 JFrame 中删除 JPanel?