.NET Core中的AsyncLocal<>
,例如CallContext.LogicGetData
/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
的任何方法。 最佳答案
使用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;
}
}