.NET Core中有CallContext.GetData / SetData的任何实现吗?

时间:2018-11-21 07:14:52

标签: c# .net multithreading .net-core

AsyncLocal<> / CallContext.LogicGetData这样的.NET Core中的

LogicSetDataGetDataSetData怎么样?
Thread.GetData/SetDataThreadStaticThreadLocal都存在相同的问题,当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中的ExecutionContext,并且它始终复制到子线程(SuppressFlow除外)。那么,有GetData / SetData的实现吗?或完成后ThreadLocal清洁的任何方式。

1 个答案:

答案 0 :(得分:2)

使用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;
    }
}