Thread.FreeNamedDataSlot(String) 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
排除處理序中所有執行緒的名稱和位置之間的關聯。 為獲得較佳的效能,請改用以 ThreadStaticAttribute 屬性標示的欄位。
public:
static void FreeNamedDataSlot(System::String ^ name);
public static void FreeNamedDataSlot (string name);
static member FreeNamedDataSlot : string -> unit
Public Shared Sub FreeNamedDataSlot (name As String)
參數
- name
- String
要釋放之資料插槽的名稱。
範例
本節包含兩個程式碼範例。 第一個範例示範如何使用標記有屬性的欄位 ThreadStaticAttribute 來保存執行緒特定的資訊。 第二個範例顯示如何使用資料位置來執行相同的動作。
第一個範例
下列範例示範如何使用標記為的欄位 ThreadStaticAttribute 來保存執行緒特定的資訊。 這項技術提供的效能比第二個範例中所示的技巧更好。
using namespace System;
using namespace System::Threading;
ref class ThreadData
{
private:
[ThreadStatic]
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
*/
using System;
using System.Threading;
class Test
{
static void Main()
{
for(int i = 0; i < 3; i++)
{
Thread newThread = new Thread(ThreadData.ThreadStaticDemo);
newThread.Start();
}
}
}
class ThreadData
{
[ThreadStatic]
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 );
}
}
/* 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
*/
Imports System.Threading
Class Test
<MTAThread> _
Shared Sub Main()
For i As Integer = 1 To 3
Dim newThread As New Thread(AddressOf ThreadData.ThreadStaticDemo)
newThread.Start()
Next i
End Sub
End Class
Class ThreadData
<ThreadStatic> _
Shared threadSpecificData As Integer
Shared Sub 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 )
End Sub
End Class
' 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
第二個範例
下列範例示範如何使用已命名的資料位置來儲存執行緒特定的資訊。
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();
}
using System;
using System.Threading;
class Test
{
public static void Main()
{
Thread[] newThreads = new Thread[4];
int i;
for (i = 0; i < newThreads.Length; i++)
{
newThreads[i] =
new Thread(new 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);
}
}
}
class Slot
{
private static Random randomGenerator = new 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);
}
}
}
Imports System.Threading
Class Test
Public Shared Sub Main()
Dim newThreads(3) As Thread
Dim i As Integer
For i = 0 To newThreads.Length - 1
newThreads(i) = _
New Thread(New ThreadStart(AddressOf Slot.SlotTest))
newThreads(i).Start()
Next i
Thread.Sleep(2000)
For i = 0 To newThreads.Length - 1
newThreads(i).Join()
Console.WriteLine("Thread_{0} finished.", _
newThreads(i).ManagedThreadId)
Next i
End Sub
End Class
Class Slot
Private Shared randomGenerator As New Random()
Public Shared Sub SlotTest()
' Set random data in each thread's data slot.
Dim slotData As Integer = randomGenerator.Next(1, 200)
Dim threadId As Integer = 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)
Dim newSlotData As Integer = _
CType(Thread.GetData(Thread.GetNamedDataSlot("Random")), Integer)
If newSlotData = slotData Then
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)
End If
End Sub
End Class
備註
重要
.NET Framework 提供兩種機制,可讓您使用執行緒區域儲存區 (TLS) :執行緒相關的靜態欄位 (也就是說,以 ThreadStaticAttribute 屬性) 和資料位置標記的欄位。 執行緒相關的靜態欄位提供比資料插槽更好的效能,並啟用編譯時間類型檢查。 如需使用 TLS 的詳細資訊,請參閱執行緒區域儲存體: Thread-Relative 靜態欄位和資料槽。
在任何執行緒呼叫之後 FreeNamedDataSlot
,任何其他 GetNamedDataSlot 使用相同名稱呼叫的執行緒都會配置與名稱相關聯的新位置。 GetNamedDataSlot
任何執行緒的後續呼叫都會傳回新的位置。 不過,任何仍有先前呼叫所傳回的執行緒,都 System.LocalDataStoreSlot GetNamedDataSlot
可以繼續使用舊的位置。
只有在呼叫之前取得的每個位置都已釋出 LocalDataStoreSlot
並進行垃圾收集時,才會釋放與該名稱相關聯的位置 FreeNamedDataSlot
。
執行緒使用本機存放區記憶體機制來儲存執行緒特定資料。 Common language runtime 會在每個進程建立時,將多個位置的資料存放區陣列配置給每個進程。 執行緒可以配置資料存放區中的資料位置、儲存並取出位置中的資料值,以及釋放位置以線上程到期之後重複使用。 每個執行緒的資料插槽都是唯一的。 沒有其他執行緒 (甚至是子執行緒) 可以取得該資料。