Archiviazione locale del thread: slot di dati e campi statici relativi ai threadThread Local Storage: Thread-Relative Static Fields and Data Slots

È possibile usare l'archiviazione locale dei thread gestiti per archiviare dati univoci relativi a un thread e un dominio dell'applicazione.You can use managed thread local storage (TLS) to store data that is unique to a thread and application domain. In .NET Framework sono disponibili due strumenti per usare l'archiviazione locale dei thread gestiti: i campi statici relativi ai thread e gli slot di dati.The .NET Framework provides two ways to use managed TLS: thread-relative static fields and data slots.

  • Usare i campi statici relativi ai thread (campi Shared relativi ai thread in Visual Basic) se è possibile prevedere con esattezza le esigenze in fase di compilazione.Use thread-relative static fields (thread-relative Shared fields in Visual Basic) if you can anticipate your exact needs at compile time. I campi statici relativi ai thread forniscono infatti prestazioni ottimali.Thread-relative static fields provide the best performance. Offrono inoltre il vantaggio di poter controllare il tipo in fase di compilazione.They also give you the benefits of compile-time type checking.

  • Se i requisiti effettivi possono essere individuati solo in fase di runtime, usare gli slot di dati.Use data slots when your actual requirements might be discovered only at run time. Gli slot di dati sono più lenti e scomodi da usare rispetto ai campi statici relativi ai thread e i dati vengono archiviati come tipo Object. Prima di usarli, quindi, è necessario eseguirne il cast al tipo corretto.Data slots are slower and more awkward to use than thread-relative static fields, and data is stored as type Object, so you must cast it to the correct type before you use it.

In C++ non gestito si usa TlsAlloc per allocare gli slot dinamicamente e __declspec(thread) per dichiarare che una variabile deve essere allocata in una risorsa di archiviazione relativa ai thread.In unmanaged C++, you use TlsAlloc to allocate slots dynamically and __declspec(thread) to declare that a variable should be allocated in thread-relative storage. I campi statici relativi ai thread e gli slot di dati forniscono la versione gestita di questo comportamento.Thread-relative static fields and data slots provide the managed version of this behavior.

In .NET Framework 4.NET Framework 4 è possibile usare la classe System.Threading.ThreadLocal<T> per creare oggetti locali di thread inizializzati in modo differito quando l'oggetto viene usato per la prima volta.In the .NET Framework 4.NET Framework 4, you can use the System.Threading.ThreadLocal<T> class to create thread-local objects that are initialized lazily when the object is first consumed. Per altre informazioni, vedere Inizializzazione differita.For more information, see Lazy Initialization.

Unicità dei dati nell'archiviazione locale dei thread gestitiUniqueness of Data in Managed TLS

Indipendentemente dal fatto che si usino i campi statici relativi ai thread o gli slot di dati, i dati presenti nell'archiviazione locale dei thread gestiti sono univoci per la combinazione di thread e dominio dell'applicazione.Whether you use thread-relative static fields or data slots, data in managed TLS is unique to the combination of thread and application domain.

  • All'interno di un dominio dell'applicazione, un thread non può modificare dati provenienti da un altro thread, anche se usano entrambi lo stesso campo o slot.Within an application domain, one thread cannot modify data from another thread, even when both threads use the same field or slot.

  • Quando un thread accede allo stesso campo o slot da più domini dell'applicazione, viene mantenuto un valore separato in ogni dominio dell'applicazione.When a thread accesses the same field or slot from multiple application domains, a separate value is maintained in each application domain.

Se, ad esempio, un thread imposta il valore di un campo statico relativo al thread, immette un altro dominio dell'applicazione e quindi recupera il valore del campo, il valore recuperato nel secondo dominio dell'applicazione differisce dal valore presente nel primo dominio dell'applicazione.For example, if a thread sets the value of a thread-relative static field, enters another application domain, and then retrieves the value of the field, the value retrieved in the second application domain differs from the value in the first application domain. L'impostazione di un nuovo valore per il campo nel secondo dominio dell'applicazione non influisce sul valore del campo nel primo dominio dell'applicazione.Setting a new value for the field in the second application domain does not affect the field's value in the first application domain.

Analogamente, se un thread ottiene lo stesso slot di dati denominato in due domini dell'applicazione diversi, i dati nel primo dominio dell'applicazione restano indipendenti dai dati presenti nel secondo dominio dell'applicazione.Similarly, when a thread gets the same named data slot in two different application domains, the data in the first application domain remains independent of the data in the second application domain.

Campi statici relativi ai threadThread-Relative Static Fields

Se si è certi che i dati sono sempre univoci in una combinazione di thread e dominio dell'applicazione, applicare l'attributo ThreadStaticAttribute al campo statico.If you know that a piece of data is always unique to a thread and application-domain combination, apply the ThreadStaticAttribute attribute to the static field. Usare il campo come qualsiasi altro campo statico.Use the field as you would use any other static field. I dati nel campo sono univoci di ogni thread che li usa.The data in the field is unique to each thread that uses it.

I campi statici relativi ai thread garantiscono prestazioni migliori rispetto agli slot di dati e offrono il vantaggio di poter controllare il tipo in fase di compilazione.Thread-relative static fields provide better performance than data slots and have the benefit of compile-time type checking.

Tenere presente che qualsiasi codice del costruttore di classe verrà eseguito sul primo thread nel primo contesto che accede al campo.Be aware that any class constructor code will run on the first thread in the first context that accesses the field. In tutti gli altri thread o contesti nello stesso dominio dell'applicazione i campi verranno inizializzati su null (Nothing in Visual Basic) se sono tipi di riferimento o sui valori predefiniti se sono tipi valore.In all other threads or contexts in the same application domain, the fields will be initialized to null (Nothing in Visual Basic) if they are reference types, or to their default values if they are value types. Di conseguenza, non è consigliabile basarsi sui costruttori delle classi per inizializzare i campi statici relativi ai thread.Therefore, you should not rely on class constructors to initialize thread-relative static fields. Al contrario, è opportuno evitare l'inizializzazione di campi statici relativi ai thread e supporre che vengano inizializzati su null (Nothing) o sui valori predefiniti.Instead, avoid initializing thread-relative static fields and assume that they are initialized to null (Nothing) or to their default values.

Slot dei datiData Slots

.NET Framework fornisce slot di dati dinamici univoci per ogni combinazione di thread e dominio dell'applicazione.The .NET Framework provides dynamic data slots that are unique to a combination of thread and application-domain. Esistono due tipi di slot di dati: con e senza nome.There are two types of data slots: named slots and unnamed slots. Entrambi vengono implementati usando la struttura LocalDataStoreSlot.Both are implemented by using the LocalDataStoreSlot structure.

Per entrambi i tipo di slot, con e senza nome, usare i metodi Thread.SetData e Thread.GetData per impostare e recuperare le informazioni nello slot.For both named and unnamed slots, use the Thread.SetData and Thread.GetData methods to set and retrieve the information in the slot. Si tratta di metodi statici che agiscono sempre sui dati per il thread che li sta eseguendo.These are static methods that always act on the data for the thread that is currently executing them.

Gli slot con nome offrono la comodità di poter essere recuperati in qualsiasi momento passandone il nome al metodo GetNamedDataSlot, anziché mantenere un riferimento a uno slot senza nome.Named slots can be convenient, because you can retrieve the slot when you need it by passing its name to the GetNamedDataSlot method, instead of maintaining a reference to an unnamed slot. Se, tuttavia, un altro componente usa lo stesso nome per la risorsa di archiviazione relativa ai thread e un thread esegue codice sia dal componente in uso che dall'altro componente, i due componenti possono danneggiare l'uno i dati dell'altro.However, if another component uses the same name for its thread-relative storage and a thread executes code from both your component and the other component, the two components might corrupt each other's data. Questo scenario presuppone che entrambi i componenti siano in esecuzione nello stesso dominio dell'applicazione e che non siano progettati per condividere gli stessi dati.(This scenario assumes that both components are running in the same application domain, and that they are not designed to share the same data.)

Vedere ancheSee Also

ContextStaticAttribute
Thread.GetNamedDataSlot
ThreadStaticAttribute
CallContext
ThreadingThreading