22.12 Getting and Setting Thread Data Using Thread Local Storage

 <  Day Day Up  >  

You want to store some data in such a way that each thread keeps its own copy of the data.


Technique

There are two different techniques available for maintaining thread-local storage in .NET: You can use a thread-local static field in a class, or you can use dynamic local data store slots.

To mark a static field as local to a thread, simply mark it with System.ThreadStaticAttribute :

 
 [ThreadStatic] static int x; 

Note that initializing thread-static fields in a static constructor is a bad idea because the static constructor is only executed once, which means only the copy of the field that is used by that thread gets initialized . Any copies associated with other threads that access the class still have their default initial values of zero/null. So you are best off not initializing these variables in any static constructor but assuming that for each thread they start as zeroed-out values.

Thread-local dynamic data store slots are far more versatile. To use them, you first call the static method, Thread.AllocateDataSlot() to allocate a slot:

 
 LocalDataStoreSlot slot = Thread.AllocateDataSlot(); 

This method returns a System.LocalDataStoreSlot reference, which refers to a data slot that you can use to store one object reference. For example, to store a string reference in this slot, use the following code:

 
 string s = "Hello"; Thread.SetData(slot, s); 

You can retrieve the stored data with the static Thread.GetData() method, which returns an object reference:

 
 string retrievedString = (string)Thread.GetData(slot); Console.WriteLine(retrievedString); 

GetData() returns null if no data is placed in the slot associated with the LocalDataStoreSlot parameter that it is passed.

So far, this process simply looks like a roundabout way to store an object reference. The key, however, is that a given LocalDataStoreSlot reference always accesses a thread-specific data slot. So with the preceding code snippet, the call to Thread.GetData() only retrieves the string "Hello" if it is executed on the same thread that executed the previous SetData() call. If that same statement with the same slot reference as a parameter is expected on any other thread, then it returns null (unless that other thread also previously used that LocalDataStoreSlot to store some object reference).

There are no restrictions on how many local data stores a given application, or a given thread, can use:

 
 LocalDataStoreSlot slot = Thread.AllocateDataSlot(); LocalDataStoreSlot slot2 = Thread.AllocateDataSlot(); LocalDataStoreSlot slot3 = Thread.AllocateDataSlot(); Thread.SetData(slot, "Hello!"); Thread.SetData(slot2, "Hello again!"); Thread.SetData(slot3, "Bye!"); 

Comments

Which of these two techniques you use depends largely on your situation. In general, using thread-local static fields is only possible if you know at compile time which data you need to store local to threads and whether the data is static. If you need to store instance fields in thread-local storage, or you need to determine dynamically at runtime which data must be stored in thread-local storage, then you need to use the LocalDataStoreSlot method.

The simplest way to store instance fields in thread-local storage is to use a field of type LocalDataStoreSlot and wrap it with a property. If we assume that thread-local storage is required for a field of type MyLocalType , the code would look like this:

 
 class MyClass {         LocalDataStoreSlot tlsField = Thread.AllocateDataSlot();         MyLocalType TlsField         {                 get                 {                         return (MyLocalType)Thread.GetData(slot);                 }                 set                 {                         Thread.SetData(slot, tlsField);                 }         } } 

Bear in mind that in most cases, explicit thread-local storage is only important for fields of types. Variables defined locally to a method are normally available only in that method, and therefore to the thread that is executing that method, unless such variables are explicitly passed to some code being executed by another thread.

 <  Day Day Up  >  


Microsoft Visual C# .Net 2003
Microsoft Visual C *. NET 2003 development skills Daquan
ISBN: 7508427505
EAN: 2147483647
Year: 2003
Pages: 440

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net