AsyncLocal<>
/ CallContext.LogicGetData
这样的.NET Core中的 LogicSetData
。 GetData
和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
中的ExecutionContext
,并且它始终复制到子线程(SuppressFlow除外)。那么,有GetData
/ SetData
的实现吗?或完成后ThreadLocal
清洁的任何方式。
答案 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;
}
}