首页 > 解决方案 > .NET Core 中有 CallContext.GetData / SetData 的实现吗?

问题描述

AsyncLocal<>在 .NET Core 中,例如CallContext.LogicGetData/ LogicSetDataGetData和怎么样SetData
Thread.GetData/SetData, ThreadStatic,ThreadLocal所有这些都有相同的问题,当Thread完成时,这些值不会被清除,如果这些Thread重用(或者可能Thread Id重用),则LocalValue已经存在。

class Program
{
    [ThreadStatic]
    private static string Static;
    private static ThreadLocal<string> Local = new ThreadLocal<string>(false);
    private static LocalDataStoreSlot Slot = Thread.AllocateDataSlot();

    static void Main(string[] args)
    {
        var threadIds = new List<int>();
        for (var i = 0; i < 100; i++)
        {
            Task.Run(() =>
            {
                if (threadIds.Contains(Thread.CurrentThread.ManagedThreadId))
                {
                    if(Static == null || Local.Value == null || Thread.GetData(Slot) == null)
                    {
                        // never get in
                    }
                    else
                    {
                        // same thread id always already exists value
                    }
                }
                else
                {
                    threadIds.Add(Thread.CurrentThread.ManagedThreadId);
                    if (Static == null && Local.Value == null && Thread.GetData(Slot) == null)
                    {
                        var threadId = Thread.CurrentThread.ManagedThreadId.ToString();
                        Static = threadId;
                        Local.Value = threadId;
                        Thread.SetData(Slot, threadId);
                    }
                    else
                    {
                        //never get in
                    }
                }
            }).Wait();
        }

        Console.WriteLine("Press any key to continue...");
        Console.ReadKey();
    }
}

我知道怎么CallContext做,它只是将LogicalCallContext值复制到子线程而不复制IllogicalCallContext. 但是 .NET Core 只IAsyncLocalValueMap在.NET Core 中ExecutionContext,它总是复制到子线程(SuppressFlow 除外)。那么,有没有GetData/的实现SetData?或完成后的任何清洁方式ThreadLocal

标签: c#.netmultithreading.net-core

解决方案


使用 AsyncLocal 的更改处理程序在线程更改时清除值?

private static AsyncLocal<string> AsyncLocal
    = new AsyncLocal<string>(ThreadContextChanged);

private static void ThreadContextChanged(AsyncLocalValueChangedArgs<string> changedArgs)
{
    if (changedArgs.ThreadContextChanged &&
        changedArgs.CurrentValue != null)
    {
        AsyncLocal.Value = null;
    }
}

推荐阅读