【问题标题】:.NET Core equivalent of CallContext.LogicalGet/SetData.NET Core 等效于 CallContext.LogicalGet/SetData
【发布时间】:2017-02-15 06:35:02
【问题描述】:

我正在尝试将使用 CallContext.LogicalGet/SetData 的现有 .net 应用程序移入 .net 核心。

当网络请求到达应用程序时,我将 CorrelationId 保存在 CallContext 中,并且每当我需要稍后记录某些内容时,我都可以轻松地从 CallContext 中收集它,而无需将其传输到任何地方。

由于 CallContext 是 System.Messaging.Remoting 的一部分,因此在 .net 核心中不再支持它,有哪些选项?

我看到的一个版本是可以使用 AsyncLocal (How do the semantics of AsyncLocal differ from the logical call context?),但看起来我必须将这个变量传输到所有地方,这超出了目的,不太方便。

【问题讨论】:

    标签: .net-core callcontext


    【解决方案1】:

    当我们将库从 .Net Framework 切换到 .Net Standard 并不得不替换 System.Runtime.Remoting.Messaging CallContext.LogicalGetDataCallContext.LogicalSetData 时遇到了这个问题。

    我按照本指南替换了方法:

    http://www.cazzulino.com/callcontext-netstandard-netcore.html

    /// <summary>
    /// Provides a way to set contextual data that flows with the call and 
    /// async context of a test or invocation.
    /// </summary>
    public static class CallContext
    {
        static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();
    
        /// <summary>
        /// Stores a given object and associates it with the specified name.
        /// </summary>
        /// <param name="name">The name with which to associate the new item in the call context.</param>
        /// <param name="data">The object to store in the call context.</param>
        public static void SetData(string name, object data) =>
            state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;
    
        /// <summary>
        /// Retrieves an object with the specified name from the <see cref="CallContext"/>.
        /// </summary>
        /// <param name="name">The name of the item in the call context.</param>
        /// <returns>The object in the call context associated with the specified name, or <see langword="null"/> if not found.</returns>
        public static object GetData(string name) =>
            state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;
    }
    

    【讨论】:

    • 大声笑,3 个月前欺骗了@kzu 的原始答案,并且不知何故比他的得票更多。
    • @benmccallum Yepp,在发布后也注意到了这一点。但是最好发布实际代码而不是链接,所以我保留了答案。
    • @Ogglas 您应该刚刚编辑了原始答案
    • @PreetSangha 是的,但那将是一个完整的重写,因为我还想提及 System.Runtime.Remoting.Messaging CallContext.LogicalGetDataCallContext.LogicalSetData
    【解决方案2】:

    您可以使用 AsyncLocal 的字典来准确模拟原始 CallContext 的 API 和行为。完整的实现示例见http://www.cazzulino.com/callcontext-netstandard-netcore.html

    【讨论】:

      猜你喜欢
      • 2018-12-21
      • 1970-01-01
      • 2019-04-12
      • 2021-06-03
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 2017-07-23
      相关资源
      最近更新 更多