Thread.AllocateNamedDataSlot(String) Metódus

Definíció

Egy elnevezett adathelyet foglal le az összes szálon. A jobb teljesítmény érdekében használjon inkább az ThreadStaticAttribute attribútummal megjelölt mezőket.

public:
 static LocalDataStoreSlot ^ AllocateNamedDataSlot(System::String ^ name);
public static LocalDataStoreSlot AllocateNamedDataSlot(string name);
static member AllocateNamedDataSlot : string -> LocalDataStoreSlot
Public Shared Function AllocateNamedDataSlot (name As String) As LocalDataStoreSlot

Paraméterek

name
String

A lefoglalni kívánt adathely neve.

Válaszok

A lefoglalt elnevezett adathely minden szálon.

Kivételek

A megadott névvel rendelkező elnevezett adathely már létezik.

Példák

Ez a szakasz két példakódot tartalmaz. Az első példa bemutatja, hogyan használható egy olyan mező, amely az ThreadStaticAttribute attribútummal van megjelölve a szálspecifikus információk tárolására. A második példa bemutatja, hogyan használhatja az adathelyet ugyanarra a célra.

Első példa

Az alábbi példa bemutatja, hogyan használható egy szálspecifikus információ tárolására megjelölt ThreadStaticAttribute mező. Ez a technika jobb teljesítményt nyújt, mint a második példában bemutatott technika.

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
 */
open System
open System.Threading

type ThreadData() =
    // Create a static variable to hold the data for each thread.
    [<ThreadStatic; DefaultValue>]
    static val mutable private threadSpecificData : int

    static member ThreadStaticDemo() =
        // Store the managed thread id for each thread in the static
        // variable.
        ThreadData.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.
        printfn $"Data for managed thread {Thread.CurrentThread.ManagedThreadId}: {ThreadData.threadSpecificData}" 

for i = 0 to 2 do 
    let newThread = Thread 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
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

Második példa

Az alábbi példa bemutatja, hogyan használható egy elnevezett adathely a szálspecifikus információk tárolására.

Note

A példakód nem használja a AllocateNamedDataSlot metódust, mert a GetNamedDataSlot metódus lefoglalja a pontot, ha még nincs lefoglalva. Ha a AllocateNamedDataSlot metódust használják, azt a program indításakor a fő szálban kell meghívni.

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);
        }
    }
}
open System
open System.Threading

module Slot =
    let private randomGenerator = Random()

    let slotTest () =
        // Set random data in each thread's data slot.
        let slotData = randomGenerator.Next(1, 200)
        let threadId = Thread.CurrentThread.ManagedThreadId

        Thread.SetData(Thread.GetNamedDataSlot "Random", slotData)

        // Show what was saved in the thread's data slot.
        printfn $"Data stored in thread_{threadId}'s data slot: {slotData, 3}"

        // Allow other threads time to execute SetData to show
        // that a thread's data slot is unique to itself.
        Thread.Sleep 1000

        let newSlotData = Thread.GetData(Thread.GetNamedDataSlot "Random") :?> int

        if newSlotData = slotData then
            printfn $"Data in thread_{threadId}'s data slot is still: {newSlotData, 3}"
        else
            printfn $"Data in thread_{threadId}'s data slot changed to: {newSlotData, 3}"

let newThreads =
    [| for _ = 0 to 3 do
           let thread = Thread Slot.slotTest
           thread.Start()
           thread |]

Thread.Sleep 2000

for tread in newThreads do
    tread.Join()
    printfn $"Thread_{tread.ManagedThreadId} finished."
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

Megjegyzések

Important

.NET Framework két mechanizmust biztosít a szál helyi tárolójának (TLS) használatára: a szál-relatív statikus mezőket (azaz a ThreadStaticAttribute attribútummal megjelölt mezőket) és az adathelyeket. A szál relatív statikus mezői sokkal jobb teljesítményt nyújtanak, mint az adathelyek, és lehetővé teszik a fordítási idő típusának ellenőrzését. A TLS használatáról további információt a Szál helyi tárolója: Thread-Relative Statikus mezők és adathelyek című témakörben talál.

A szálak helyi tárolómemória-mechanizmussal tárolják a szálspecifikus adatokat. A közös nyelvi futtatókörnyezet egy többhelyes adattártömböt foglal le minden folyamathoz a létrehozásukkor. A szál lefoglalhat egy adathelyet az adattárban, tárolhat és lekérhet egy adatértéket a pontban, és felszabadíthatja a tárolóhelyet a szál lejárata után. Az adathelyek szálonként egyediek. Más szál (még gyermekszál sem) nem tudja lekérni az adatokat.

Nem szükséges a metódust használni egy AllocateNamedDataSlot elnevezett adathely lefoglalásához, mert a GetNamedDataSlot metódus lefoglalja a pontot, ha még nem lett lefoglalva.

Note

Ha a AllocateNamedDataSlot metódust használják, akkor a program indításakor a fő szálban kell meghívni, mert kivételt eredményez, ha a megadott nevű pont már ki van foglalva. Nincs mód annak tesztelésére, hogy egy pont már ki van-e foglalva.

Az ezzel a módszerrel lefoglalt tárolóhelyeket felszabadítani kell a FreeNamedDataSlot.

A következőre érvényes:

Lásd még