c# - AsyncLocal 的语义与逻辑调用上下文有何不同?

标签 c# .net async-await .net-4.6

.NET 4.6 引入了 AsyncLocal<T>用于沿着异步控制流流动环境数据的类。我以前用过 CallContext.LogicalGet/SetData为此目的,我想知道这两者在语义上是否以及以何种方式不同(除了明显的 API 差异,如强类型和不依赖字符串键)。

最佳答案

语义几乎相同。两者都存储在 ExecutionContext 中并通过异步调用流动。

不同之处在于 API 更改(正如您所描述的)以及为值更改注册回调的能力。

从技术上讲,实现上有很大的不同,因为 CallContext 每次被复制时都会被克隆(使用 CallContext.Clone),而 AsyncLocal 的数据保存在 ExecutionContext._localValues 字典中,只复制该引用而无需任何额外工作。

为了确保更新仅在您更改 AsyncLocal 的值时影响当前流,将创建一个新字典并将所有现有值浅复制到新字典。

根据使用 AsyncLocal 的位置,这种差异对性能可能有利有弊。

现在,正如 Hans Passant 在评论中提到的那样 CallContext 最初是为远程处理而制作的,并且在不支持远程处理的地方不可用(例如 .Net Core),这可能就是为什么 AsyncLocal 被添加到框架中:

#if FEATURE_REMOTING
    public LogicalCallContext.Reader LogicalCallContext 
    {
        [SecurityCritical]
        get { return new LogicalCallContext.Reader(IsNull ? null : m_ec.LogicalCallContext); } 
    }

    public IllogicalCallContext.Reader IllogicalCallContext 
    {
        [SecurityCritical]
        get { return new IllogicalCallContext.Reader(IsNull ? null : m_ec.IllogicalCallContext); } 
    }
#endif

注意:Visual Studio SDK 中还有一个 AsyncLocal,它基本上是 CallContext 的包装器,显示了概念的相似程度:Microsoft.VisualStudio.Threading .

关于c# - AsyncLocal 的语义与逻辑调用上下文有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31707362/

相关文章:

c# - 将多个类映射到单个实体

c# - 将 WPF 扩展工具包 ColorPicker SelectedColor 属性绑定(bind)到 DependencyProperty

.net - 生成 .NET 中多个列的所有可能组合

c# - 需要有关 LINQ to SQL WHERE-clause on foreign table 的帮助

c# - 异步/等待或使用 TcpListener 开始/结束?

c# - 通过 azure 通知中心 apns 发送推送通知

c# - 对 ? 的行为感到困惑。运算符(operator)

c# - 如何在多个项目中使用 useLegacyV2RuntimeActivationPolicy?

Javascript顺序打印到文件

c# - 什么是创建可等待函数的正确方法