Szál helyi tárolója: Szál relatív statikus mezői és adattárolói

A felügyelt szál helyi tárolója (TLS) használatával olyan adatokat tárolhat, amelyek egyediek a szál és az alkalmazástartomány számára. A .NET két módszert kínál a felügyelt TLS használatára: a szál-relatív statikus mezőket és az adathelyeket.

  • Használjon szál-relatív statikus mezőket (a Visual Basic szál-relatív Shared mezőit), ha a fordításkor előre tudja látni a pontos igényeket. A szál relatív statikus mezői biztosítják a legjobb teljesítményt. Emellett a fordítási idő típusú ellenőrzés előnyeit is biztosítják.

  • Használjon adathelyeket, ha a tényleges követelmények csak futásidőben fedezhetők fel. Az adathelyek használata lassabb és kényelmetlenebb, mint a szál relatív statikus mezői, és az adatok típusként Objectvannak tárolva, ezért használat előtt a megfelelő típusba kell őket beszűkíteni.

A nem felügyelt C++-ban dinamikusan oszthat TlsAlloc ki tárolóhelyeket, és __declspec(thread) deklarálhatja, hogy egy változót szál-relatív tárolóban kell lefoglalni. Ennek a viselkedésnek a felügyelt verzióját a szál relatív statikus mezői és adathelyei biztosítják.

Az System.Threading.ThreadLocal<T> osztály használatával olyan szálalapú objektumokat hozhat létre, amelyek az objektum első felhasználásakor lazán inicializálódnak. További információ: Lusta inicializálás.

Az adatok egyedisége a felügyelt TLS-ben

Függetlenül attól, hogy szál-relatív statikus mezőket vagy adathelyeket használ, a felügyelt TLS-ben lévő adatok egyediek a szál és az alkalmazástartomány kombinációjára.

  • Egy alkalmazástartományon belül az egyik szál nem tudja módosítani egy másik szál adatait, még akkor sem, ha mindkét szál ugyanazt a mezőt vagy pontot használja.

  • Ha egy szál több alkalmazástartományból fér hozzá ugyanahhoz a mezőhöz vagy ponthoz, minden alkalmazástartományban külön érték marad fenn.

Ha például egy szál egy szál relatív statikus mezőjének értékét állítja be, egy másik alkalmazástartományt ad meg, majd lekéri a mező értékét, a második alkalmazástartományban lekért érték eltér az első alkalmazástartomány értékétől. A második alkalmazástartományban lévő mező új értékének beállítása nem befolyásolja a mező értékét az első alkalmazástartományban.

Hasonlóképpen, ha egy szál ugyanazt az elnevezett adathelyet kapja két különböző alkalmazástartományban, az első alkalmazástartomány adatai függetlenek maradnak a második alkalmazástartomány adataitól.

Szál-relatív statikus mezők

Ha tudja, hogy egy adatelem mindig egyedi a szál és az alkalmazástartomány kombinációjában, alkalmazza az ThreadStaticAttribute attribútumot a statikus mezőre. Használja a mezőt úgy, ahogyan bármely más statikus mezőt használna. A mezőben lévő adatok egyediek az azt használó összes szálra vonatkozóan.

A szál relatív statikus mezői jobb teljesítményt nyújtanak, mint az adathelyek, és a fordítási idő típusú ellenőrzés előnye.

Vegye figyelembe, hogy az osztálykonstruktor-kód az első szálon fog futni az első környezetben, amely hozzáfér a mezőhöz. Az ugyanabban az alkalmazástartományban lévő összes többi szálban vagy kontextusban a mezők inicializálása a (Visual Basicben) lesz, ha hivatkozástípusok, vagy ha értéktípusok, akkor az alapértelmezett értékükre lesznek inicializálvanullNothing. Ezért nem szabad osztálykonstruktorokra támaszkodnia a szál relatív statikus mezőinek inicializálásához. Ehelyett kerülje a szál relatív statikus mezőinek inicializálását, és feltételezze, hogy () vagy az alapértelmezett értékekre vannak inicializálvanullNothing.

Adathelyek

A .NET dinamikus adathelyeket biztosít, amelyek egyediek a szál és az alkalmazástartomány kombinációjára. Kétféle adathely létezik: elnevezett és névtelen tárolóhelyek. Mindkettő a LocalDataStoreSlot struktúra használatával implementálva van.

A névvel ellátott és a névtelen pontok esetében a pontban lévő információk beállításához és Thread.GetData lekéréséhez használja a Thread.SetData metódusokat és a metódusokat. Ezek statikus metódusok, amelyek mindig az éppen végrehajtó szál adataira reagálnak.

Az elnevezett pontok kényelmesek lehetnek, mert szükség esetén lekérheti a pontot úgy, hogy átadja a nevét a GetNamedDataSlot metódusnak ahelyett, hogy egy névtelen pontra mutató hivatkozást tartana fenn. Ha azonban egy másik összetevő ugyanazt a nevet használja a szál relatív tárolójához, és egy szál az ön és a másik összetevő kódját is végrehajtja, a két összetevő megsérülhet egymás adataiban. (Ez a forgatókönyv feltételezi, hogy mindkét összetevő ugyanabban az alkalmazástartományban fut, és nem ugyanazon adatok megosztására vannak kialakítva.)

Lásd még