【问题标题】:What are Context class SychronizationContext class in C#?什么是 C# 中的 Context 类 SychronizationContext 类?
【发布时间】:2020-04-08 08:56:37
【问题描述】:

我是 C# 多线程的新手,我正在学习一些关于多线程、异步编程和并行编程的教程,其中我遇到了某些术语,例如“上下文”、“上下文切换”和“延续到原始上下文”。在查看了.NET文档后,我在System.Threading命名空间中发现了一些类似的类和属性,例如返回Context类型数据的“CurrentContext”,并且在System.Threading命名空间中有“SynchronizationContext”类。

谁能解释一下这些术语、属性和类?我觉得很难掌握。

谢谢。

【问题讨论】:

标签: c# multithreading asynchronous


【解决方案1】:

SynchronizationContext 是一个较旧的 API,旨在允许多个线程相互协调。特别是,这在历史上来自诸如 winforms 之类的 UI 世界,其中有一个主 UI 线程,如果您有后台工作正在进行,它可能需要按顺序将 返回 到 UI 线程执行 UI 更新等操作。有多种机制可以做到这一点,SynchronizationContext 就是其中之一。本质上,这公开了两个 API:PostSend(主要区别在于 Send 阻塞等待工作完成)。

现在,与此完全不同的是,async/await 是一个不同用于执行异步代码的 API 模型,即

var foo = await BarAsync();`
SomethingElse(foo);

这里,如果BarAsync同步完成,代码只是保持正常运行,SomethingElse立即执行;但如果BarAsync 返回incomplete - 即异步 - 然后线程展开,将控制权返回到它来自的任何地方,以及延续BarAsync 的结果可用时,将运行SomethingElse 的钩子。

这两个模型相交的地方是await 背后的实现知道SynchronizationContext 的存在,并且如果存在一个,它将(默认情况下)捕获同步上下文当时存在,并通过该同步上下文 (Post) 恢复执行,基于您可能想要回到那个线程模型,而不是任何触发的线程模型BarAsync 的完成。可以使用ConfigureAwait 配置(禁用)此行为:

var foo = await BarAsync().ConfigureAwait(false);`
SomethingElse(foo);

现在它将捕获同步上下文,并且当不完整的操作恢复时,不会调用额外的间接。这对于避免额外的上下文切换很有用,但意味着某些事情(例如更新 UI)可能会失败。通常(但不普遍),应用程序代码很少使用ConfigureAwait,而库通常使用ConfigureAwait

【讨论】:

    猜你喜欢
    • 2015-05-13
    • 1970-01-01
    • 2015-01-17
    • 2010-12-12
    • 2013-05-27
    • 2017-11-03
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多