Reputation: 172
AsyncLocal<>
in .NET Core like CallContext.LogicGetData
/LogicSetData
. How about GetData
and SetData
?
Thread.GetData/SetData
, ThreadStatic
, ThreadLocal
all of these has same problem, when Thread
finish, these value will not clean, and if these Thread
reuse(or maybe Thread Id
reuse), the LocalValue is already exists.
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();
}
}
I know how CallContext
do, it just copy LogicalCallContext
values to child thread and do not copy IllogicalCallContext
. But .NET Core only IAsyncLocalValueMap
in ExecutionContext
, and it always copy to child thread(except SuppressFlow). So, is there any implement of GetData
/SetData
? or any way to clean ThreadLocal
when its finished.
Upvotes: 5
Views: 2801
Reputation: 3431
Use a change handler for the AsyncLocal to clear the value when the thread changes?
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;
}
}
Upvotes: 2