Thread::FreeNamedDataSlot Method (String^)
Eliminates the association between a name and a slot, for all threads in the process. For better performance, use fields that are marked with the ThreadStaticAttribute attribute instead.
Assembly: mscorlib (in mscorlib.dll)
public: [HostProtectionAttribute(SecurityAction::LinkDemand, SharedState = true, ExternalThreading = true)] static void FreeNamedDataSlot( String^ name )
Parameters
- name
-
Type:
System::String^
The name of the data slot to be freed.
Important |
|---|
The .NET Framework provides two mechanisms for using thread local storage (TLS): thread-relative static fields (that is, fields that are marked with the ThreadStaticAttribute attribute) and data slots. Thread-relative static fields provide much better performance than data slots, and enable compile-time type checking. For more information about using TLS, see Thread Local Storage: Thread-Relative Static Fields and Data Slots. |
After any thread calls FreeNamedDataSlot, any other thread that calls GetNamedDataSlot with the same name will allocate a new slot associated with the name. Subsequent calls to GetNamedDataSlot by any thread will return the new slot. However, any thread that still has a System::LocalDataStoreSlot returned by an earlier call to GetNamedDataSlot can continue to use the old slot.
A slot that has been associated with a name is released only when every LocalDataStoreSlot that was obtained prior to the call to FreeNamedDataSlot has been released and garbage-collected.
Threads use a local store memory mechanism to store thread-specific data. The common language runtime allocates a multi-slot data store array to each process when it is created. The thread can allocate a data slot in the data store, store and retrieve a data value in the slot, and free the slot for reuse after the thread expires. Data slots are unique per thread. No other thread (not even a child thread) can get that data.
This section contains two code examples. The first example shows how to use a field that is marked with the ThreadStaticAttribute attribute to hold thread-specific information. The second example shows how to use a data slot to do the same thing.
First Example
The following example shows how to use a field that is marked with ThreadStaticAttribute to hold thread-specific information. This technique provides better performance than the technique that is shown in the second example.
using namespace System; using namespace System::Threading; ref class ThreadData { private: [ThreadStaticAttribute] static int threadSpecificData; public: static void ThreadStaticDemo() { // Store the managed thread id for each thread in the static // variable. threadSpecificData = Thread::CurrentThread->ManagedThreadId; // Allow other threads time to execute the same code, to show // that the static data is unique to each thread. Thread::Sleep( 1000 ); // Display the static data. Console::WriteLine( "Data for managed thread {0}: {1}", Thread::CurrentThread->ManagedThreadId, threadSpecificData ); } }; int main() { for ( int i = 0; i < 3; i++ ) { Thread^ newThread = gcnew Thread( gcnew ThreadStart( ThreadData::ThreadStaticDemo )); newThread->Start(); } } /* This code example produces output similar to the following: Data for managed thread 4: 4 Data for managed thread 5: 5 Data for managed thread 3: 3 */
Second Example
The following example demonstrates how to use a named data slot to store thread-specific information.
using namespace System; using namespace System::Threading; ref class Slot { private: static Random^ randomGenerator = gcnew Random(); public: static void SlotTest() { // Set random data in each thread's data slot. int slotData = randomGenerator->Next(1, 200); int threadId = Thread::CurrentThread->ManagedThreadId; Thread::SetData( Thread::GetNamedDataSlot("Random"), slotData); // Show what was saved in the thread's data slot. Console::WriteLine("Data stored in thread_{0}'s data slot: {1,3}", threadId, slotData); // Allow other threads time to execute SetData to show // that a thread's data slot is unique to itself. Thread::Sleep(1000); int newSlotData = (int)Thread::GetData(Thread::GetNamedDataSlot("Random")); if (newSlotData == slotData) { Console::WriteLine("Data in thread_{0}'s data slot is still: {1,3}", threadId, newSlotData); } else { Console::WriteLine("Data in thread_{0}'s data slot changed to: {1,3}", threadId, newSlotData); } } }; ref class Test { public: static void Main() { array<Thread^>^ newThreads = gcnew array<Thread^>(4); int i; for (i = 0; i < newThreads->Length; i++) { newThreads[i] = gcnew Thread(gcnew ThreadStart(&Slot::SlotTest)); newThreads[i]->Start(); } Thread::Sleep(2000); for (i = 0; i < newThreads->Length; i++) { newThreads[i]->Join(); Console::WriteLine("Thread_{0} finished.", newThreads[i]->ManagedThreadId); } } }; int main() { Test::Main(); }
Available since 1.1
