This post is also
available in english here
.
J'ai récemment cherché un moyen de passer automatiquement des informations du contexte d'appel d'une thread vers tout autre thread créée à partir de la première. Cela peut-être utile pour de multiples raison, comme par exemple avoir des informations contextuelles placées dans le TLS à propos de l'utilisateur courant, ou pour tout autre information contextuelle spécifique à l'application.
Il est possible d'obtenir ce comportement en entourant le point d'entrée d'une thread de code qui va passer les informations à la nouvelle thread. C'est généralement assez fastidieux, voire complexe lorsqu'il s'agit de passer des informations générées en interne par un framework, puisqu'il faut absolument intercepter toutes les créations de thread.
Il existe un moyen pour faire cela en utilisant la class CallContext, et en particulier les méthodes GetData/SetData. Le problème est que si l'on place des données dans le CallContext, elles ne seront pas passées à une nouvelle thread. En pratique, pour que les données soient passées, il suffit que l'objet placé dans le CallContext implémente l'interface ILogicalThreadAffinative.
C'est une sorte d'interface marqueur qui permet d'éviter de faire transiter des données entre Threads lorsqu'elle n'y sont pas destinées.
Il est également intéressant de noter que les types marqués avec ILogicalThreadAffinative seront passés aux threads créées par le Thread Pool, et donc aux delegates placés dans la queue par l'appel à la méthode BeginInvoke qui est générée par le compilateur C#.
Enfin, dans le cas d'un appel distant en Remoting, tout type marqué avec ILogicalThreadAffinative sera sérialisé vers le contexte d'appel distant, puis sérialisé à nouveau en retour vers le contexte local.
Etre capable de faire du pas-à-pas dans le code du Framework a été d'une grande aide pour comprendre tout cela ;)