Is it permissible to cache/reuse Thread.GetNamedSlot between threads?
Can the result of the
GetNamedDataSlot
function be cached (and reused across all threads) or should it be invoked in/for every thread?
Unfortunately, the documentation isn't 100% clear on this point. Some interesting passages include…
From Thread.GetNamedDataSlot Method (String):
Data slots are unique per thread. No other thread (not even a child thread) can get that data
And from LocalDataStoreSlot Class:
The data slots are unique per thread or context; their values are not shared between the thread or context objects
At best, these make clear that each thread gets its own copy of the data. But the passages can be read to mean either that the LocalDataStoreSlot
itself is per-thread, or simply the data to which it refers is per-thread. I believe it's the latter, but I can't point to a specific MSDN page that says so.
So, we can look at the implementation details:
There is a single slot manager per process, which is used to maintain all of the per-thread slots. A LocalDataStoreSlot
returned in one thread can be passed to another thread and used there, and it would be owned by the same manager, and use the same slot index (because the slot table is also per-process). It also happens that the Thread.SetData()
method will implicitly create the thread-local data store for that slot if it doesn't already exist.
The Thread.GetData()
method simply returns null
if you haven't already set a value or the thread-local data store hasn't been created. So, the behavior of GetData()
remains consistent whether or not you have called SetData()
in that thread already.
Since the slots are managed at a process-level basis, you can reuse the LocalDataStoreSlot
values across threads. Once allocated, the slot is used up for all threads, and the data stored for that slot will be unique for each thread. Sharing the LocalDataStoreSlot
value across threads shares the slot, but even for a single slot, you get thread-local storage for each thread.
Indeed, looking at it this way, the implementation you show would be the desirable way to use this API. After all, it's an alternative to [ThreadStatic]
, and the only way to ensure a different LocalDataStoreSlot
value for each thread in your code would be either to use [ThreadStatic]
(which if you wanted to use, you should have just used for the data itself), or to maintain your own dictionary of LocalDataStoreSlot
values, indexed presumably by Thread.ManagedThreadId
.
Personally, I'd just use [ThreadStatic]
. MSDN even recommends this, and it has IMHO clearer semantics. But if you want to use LocalDataStoreSlot
, it seems to me that the implementation you have is correct.