Stockage local des threads : champs statiques et emplacements de données relatifs à un thread

Mise à jour : novembre 2007

Vous pouvez utiliser le stockage local des threads managés (TLS, Thread Local Storage) pour stocker des données spécifiques à un thread et à un domaine d'application. Le .NET Framework offre deux moyens d'utiliser le TLS managé : champs statiques relatifs à un thread et emplacements de données.

  • Utilisez des champs statiques relatifs à un thread (champs Shared relatifs à un thread dans Visual Basic) si vous pouvez anticiper vos besoins précis au moment de la compilation. Les champs statiques relatifs à un thread fournissent la meilleure performance. Ils vous offrent également les avantages de la vérification de type au moment de la compilation.

  • Utilisez les emplacements de données lorsque vos spécifications réelles peuvent être découvertes uniquement au moment de l'exécution. Les emplacements de données sont plus lents et plus maladroits à l'utilisation que les champs statiques relatifs à un thread, et les données sont stockées comme type Object, ce qui fait que vous devez effectuer un cast au type correct avant utilisation.

Dans le code C++ non managé, vous utilisez TlsAlloc pour allouer dynamiquement des emplacements et __declspec(thread) pour déclarer qu'une variable doit être allouée dans le stockage relatif aux threads. Les champs statiques relatifs à thread et les emplacement de données fournissent la version managée de ce comportement.

Unicité de données dans TLS managé

Que vous utilisiez des champs statiques relatifs à un thread ou des emplacements de données, les données dans TLS managé sont uniques à la combinaison de thread et au domaine d'application.

  • Dans un domaine d'application, un thread ne peut pas modifier de données d'un autre thread, même lorsque les deux threads utilisent le même champ ou emplacement.

  • Lorsqu'un thread accède au même champ ou emplacement à partir de plusieurs domaines d'application, une valeur séparée est maintenue dans chaque domaine d'application.

Par exemple, si un thread définit la valeur d'un champ statique relatif à un thread, accède à un autre domaine d'application, puis récupère la valeur du champ, la valeur récupérée dans le deuxième domaine d'application diffère de la valeur dans le premier domaine d'application. La définition d'une nouvelle valeur pour le champ dans le deuxième domaine d'application n'affecte pas la valeur du champ dans le premier domaine d'application.

De la même façon, lorsqu'un thread obtient le même emplacement de données nommé dans deux domaines d'application différents, les données dans le premier domaine d'application restent indépendantes des données dans le deuxième domaine d'application.

Champs statiques relatifs à un thread

Si vous savez que certaines données sont toujours uniques à un thread et combinaison de domaines d'application, appliquez l'attribut ThreadStaticAttribute au champ statique. Utilisez le champ comme vous utiliseriez tout autre champ statique. Les données dans le champ sont uniques à chaque thread qui les utilise.

Les champs statiques relatifs à un thread fournissent des performances supérieures à celles de l'emplacement des données et offrent l'avantage de la vérification de type au moment de la compilation.

Sachez que tout code de constructeur de classe s'exécutera sur le premier thread dans le premier contexte qui accède au champ. Dans tous les autres threads ou contextes dans le même domaine d'application, les champs sont initialisés avec la valeur null (Nothing dans Visual Basic) s'il s'agit de types référence ou avec leur valeur par défaut s'il s'agit de types valeur. En conséquence, vous ne devriez pas vous reposer sur les constructeurs de classe pour initialiser des champs statiques relatifs à un thread. Au contraire, évitez d'initialiser les champs statiques relatifs à un thread et supposez qu'ils sont initialisés avec la valeur null (Nothing) ou avec leurs valeurs par défaut.

Emplacements des données

Le .NET Framework fournit des emplacements de données dynamiques spécifiques à une combinaison d'un thread et d'une combinaison application-domaine. Il existe deux types d'emplacements de données : les emplacements nommés et les emplacements sans nom. Les deux sont implémentés en utilisant la structure LocalDataStoreSlot.

Pour les emplacements nommés et sans nom, utilisez les méthodes Thread.SetData et Thread.GetData pour définir et récupérer les informations dans l'emplacement. Ce sont des méthodes statiques qui toujours agissent sur les données pour le thread qui les exécute actuellement.

Les emplacements nommés peuvent être commodes, parce que vous pouvez récupérer l'emplacement lorsque vous en avez besoin en passant son nom à la méthode GetNamedDataSlot, au lieu de maintenir une référence à un emplacement sans nom. Toutefois, si un autre composant utilise le même nom pour son stockage relatif à un thread et qu'un thread exécute du code à partir de votre composant et de l'autre composant, chaque composant risque d'endommager les données de l'autre. (Ce scénario suppose que les deux composants s'exécutent dans le même domaine d'application, et qu'ils ne sont pas conçus pour partager les mêmes données.)

Voir aussi

Référence

ContextStaticAttribute

Thread.GetNamedDataSlot

ThreadStaticAttribute

CallContext

Autres ressources

Threading managé