.net core .NET核心等效于CallContext.LogicalGet/SetData

.net core .NET核心等效于CallContext.LogicalGet/SetData,.net-core,callcontext,.net Core,Callcontext,我正在尝试将使用CallContext.LogicalGet/SetData的现有.net应用程序迁移到.net核心 当web请求点击应用程序时,我会在CallContext中保存一个CorrelationId,当我以后需要记录某个内容时,我可以轻松地从CallContext中收集它,而无需到处传输它 由于.net core不再支持CallContext,因为它是System.Messaging.Remoting的一部分。有哪些选项 我看到的一个版本是可以使用AsyncLocal(),但是看起来

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

当web请求点击应用程序时,我会在CallContext中保存一个CorrelationId,当我以后需要记录某个内容时,我可以轻松地从CallContext中收集它,而无需到处传输它

由于.net core不再支持CallContext,因为它是System.Messaging.Remoting的一部分。有哪些选项


我看到的一个版本是可以使用AsyncLocal(),但是看起来我必须将这个变量传输到所有地方,这与目的不符,它没有那么方便。

您可以使用AsyncLocal字典精确模拟原始CallContext的API和行为。有关完整的实现示例,请参阅。

当我们将一个库从.Net Framework切换到.Net标准时,出现了此问题,并且必须替换
System.Runtime.Remoting.Messaging
CallContext.LogicalGetData
CallContext.LogicalSetData

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

//
///提供一种设置随调用和调用一起流动的上下文数据的方法
///测试或调用的异步上下文。
/// 
公共静态类CallContext
{
静态ConcurrentDictionary状态=新建ConcurrentDictionary();
/// 
///存储给定对象并将其与指定名称关联。
/// 
///在调用上下文中与新项关联的名称。
///要存储在调用上下文中的对象。
公共静态void SetData(字符串名称、对象数据)=>
state.GetOrAdd(name,=>newAsyncLocal()).Value=data;
/// 
///从中检索具有指定名称的对象。
/// 
///调用上下文中项的名称。
///调用上下文中与指定名称关联的对象,如果未找到,则为。
公共静态对象GetData(字符串名称)=>
state.TryGetValue(名称,输出异步本地数据)?data.Value:null;
}

lol,三个月前愚弄了@kzu的原始答案,不知何故获得了比他更多的支持票。@Benmccalum Yepp在发布后也注意到了这一点。然而,张贴实际代码而不是链接是首选,所以我保留了答案。
/// <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;
}