2016-01-27 1 views
0

Environnement: .NET Programme contenant plusieurs DLL/assemblys de code géré + natif. La première action effectuée par le programme consiste à créer une instance d'une classe (disons classA) héritée de MarshalByRefObject, dans un espace de noms (disons namespaceA).Application d'une instance commune de variables statiques à tous les threads lors de l'exécution dans le contexte de appDomain

actions effectuées dans le cadre du constructeur CLASSA:

  • Alloue nouvelle classe (par exemple ClassB). classB contient des variables statiques.
  • Créer des fils. La création réelle des threads est effectuée dans le contexte du code natif en appelant la fonction 'WinBase' 'CreateThread'.

Problème: Lors de la définition d'une instance de CLASSA dans le contexte de appdomain, ClassB variables statiques ne sont pas communs à toutes les discussions.

Le code utilisé pour charger les dll programmes et créer une instance de CLASSA au sein appdomain:

System.AppDomain app_domain = System.AppDomain.CreateDomain("app domain"); 
object winfw_host = app_domain.CreateInstanceFromAndUnwrap(@"C:\...\dll_name.dll", "namespaceA.classA"); 

Note: Lors de la définition d'une instance de CLASSA pas dans le contexte de appdomain, les variables statiques ClassB sont communs à tous les threads.

Question:

Je me serais attendu à même comportement (AppDomain et contexte non AppDomain), quelle est la raison de la différence?

Est-il possible d'appliquer une instance commune de variables statiques à tous les threads lors de l'exécution dans le contexte de appDomain?

Répondre

0

La portée d'une variable statique est exactement le domaine AppDomain. Afin de récupérer cette limitation, je recommanderais d'utiliser une manière compliquée.

Vous sélectionnez un AppDomain (disons A). La classe AppDomain expose les méthodes non statiques suivantes.

GetData(String) 
SetData(String, Object) 

Essayez de stocker la valeur partagée par tous AppDomain par A.SetData (« votre clé », valeur), et récupérer la valeur par A.GetData (« clé »)

Vous devrez pense également à l'accès sécurisé aux threads lors de l'accès à AppDomain A.

+0

Le deuxième paramètre de la méthode "SetData" doit être soit un type de valeur, soit un type héritant de la classe MarshalByRefObject. –

0

Microsoft a approuvé le comportement attendu lors de la création de threads multilingues dans un contexte appDomian, les variables statiques ne doivent pas être communes à tous les threads (à la différence de non-appDomain, un variable statique pour tous les threads) et c'est ainsi que C++/CLI a été implémenté. Pour ce type d'exigence, il est suggéré de créer un type de délégué pour renvoyer l'appel de méthode gérée afin qu'il puisse être transmis au code natif dans les threads natifs, car les délégués conservent ces informations AppDomain sur les threads natifs. Fondamentalement, vous créez le délégué géré, allouer un GCHandle pour le délégué pour le référencer dans votre code C++ natif, puis appelez Marshal :: GetFunctionPointerForDelegate sur le GCHandle pour obtenir le pointeur de la fonction native vers le délégué. La dernière partie nécessite une distribution statique de l'IntPtr à votre type de fonction natif.Vous pouvez ensuite passer ce pointeur de fonction natif que vous obtenez à travers les threads.