Is it allowed to cache / reuse Thread.GetNamedSlot between threads?

The Thread.GetNamedDataSlot method gets a slot name that can be used with Thread.SetData .

Can the result of the GetNamedDataSlot function be cached (and reused for all threads) or should be called in / for each thread?

The documentation does not explicitly state that "should not be" reused, although it does not say that this may be so. In addition, the example shows GetNamedDataSlot used at each GetData / SetData site; even within the same topic.

For example (note that the BarSlot slot BarSlot not created / assigned to all the specific flows that TLS accesses);

 public Foo { private static LocalStorageDataSlot BarSlot = Thread.GetNamedDataSlot("foo_bar"); public static void SetMethodCalledFromManyThreads(string awesome) { Thread.SetData(BarSlot, awesome); } public static void ReadMethodCalledFromManyThreads() { Console.WriteLine("Data:" + Thread.GetData(BarSlot)); } } 

I ask this question in relation to the structure of the code; any increase in microproductivity, if any, is a freebie. Any critical problems or poor performance when reused makes it unviable.

+5
source share
1 answer

Is it possible to cache the result of the GetNamedDataSlot function (and reuse it for all threads), or should it be called in / for each thread?

Unfortunately, at this stage, the documentation is not 100% understandable. Some interesting places include & hellip;

From Thread.GetNamedDataSlot (String) Method :

Data slots are unique to each stream. No other thread (even a child thread) can receive this data

And from the LocalDataStoreSlot Class :

Data slots are unique to each stream or context; their values ​​are not shared between stream or context objects.

At best, they make it clear that each thread gets its own copy of the data. But passes can be considered meaning that LocalDataStoreSlot itself is a stream, or just the data to which it refers refers to streams. I believe this is the last, but I can’t point to a specific MSDN page that says so.

So, we can see the implementation details :

Each process has one slot manager, which is used to support all the slots for each thread. A LocalDataStoreSlot returned in one thread can be transferred to another thread and used there, and it will belong to the same manager and use the same slot index (since the slot table is also per-process). It also happens that the Thread.SetData() method will implicitly create a local thread data store for this slot, if it does not already exist.

The Thread.GetData() method simply returns null if you have not set a value yet, or if a local thread data store has not been created. Thus, the behavior of GetData() remains consistent regardless of whether you have already called SetData() on this thread.

Since slots are process-level controlled, you can reuse LocalDataStoreSlot values ​​for streams. After allocation, the slot is used for all streams, and the data stored for this slot will be unique for each stream. Sharing the LocalDataStoreSlot value in streams shares this slot, but even for one slot you get a local stream store for each stream.

In fact, looking at it that way, the implementation you are showing would be a desirable way to use this API. After all, this is an alternative to [ThreadStatic] , and the only way to provide a different LocalDataStoreSlot value for each thread in your code is to either use [ThreadStatic] (which, if you wanted to use it, you should just use it for the data itself) or to maintain your own a dictionary of LocalDataStoreSlot values ​​indexed presumably using Thread.ManagedThreadId .

Personally, I just use [ThreadStatic] . MSDN even recommends this, and it has clearer semantics of IMHO. But if you want to use LocalDataStoreSlot , it seems to me that your implementation is correct.

+5
source

Source: https://habr.com/ru/post/1269735/


All Articles