Question

Voici le problème principal: j'ai une application .NET qui utilise COM interop dans une séparer AppDomain. Le composant COM semble charger les assemblys dans le domaine par défaut, plutôt que le domaine AppDomain à partir duquel le composant COM est appelé.

Ce que je veux savoir, c'est: s'agit-il du comportement attendu ou est-ce que je fais quelque chose de mal pour que ces assemblys liés à COM soient chargés dans le mauvais AppDomain? Veuillez voir une description plus détaillée de la situation ci-dessous ...

L'application est composée de 3 assemblys: - le fichier EXE principal, le point d'entrée de l'application. - common.dll, ne contenant qu'une interface IController (dans le style IPlugin) - controller.dll, contenant une classe de contrôleurs qui implémente IController et MarshalByRefObject. Cette classe effectue tout le travail et utilise COM interop pour interagir avec une autre application.

La partie pertinente du fichier EXE principal ressemble à ceci:

AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);

Le fichier common.dll contient uniquement ces 2 éléments:

public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
    ControllerRunResult Run();
}

Et le controller.dll contient cette classe (qui appelle également le truc d'interopérabilité COM):

public class Controller: IController, MarshalByRefObject

Lors de la première exécution de l'application, Assembly.GetAssemblies () se présente comme prévu, common.dll étant chargé à la fois dans AppDomains et controller.dll uniquement dans le domaine du contrôleur. Après avoir appelé c.Run (), je constate cependant que des assemblages liés au matériel d'interopérabilité COM ont été chargés dans le répertoire AppDomain par défaut, et NON dans le répertoire AppDomain à partir duquel l'interopérabilité COM a lieu.

Pourquoi cela pourrait-il se produire?

Et si cela vous intéresse, voici un peu de contexte:

À l'origine, il s'agissait d'une application 1 AppDomain. L'interface COM avec laquelle il s'interface est une API de serveur instable sur de longues périodes d'utilisation. Lorsqu'une exception COMException (sans information de diagnostic utile quant à sa cause) se produit à partir du matériel COM, l'application entière doit être redémarrée avant que la connexion COM ne fonctionne à nouveau. La simple reconnexion au serveur d'applications COM entraîne à nouveau des exceptions COM immédiates. Pour faire face à cela, j'ai essayé de déplacer les éléments d'interopérabilité COM dans un AppDomain séparé afin de pouvoir décharger l'AppDomain dans lequel il se produit, créer un nouveau et le redémarrer, sans avoir à redémarrer manuellement l'application. . C’était la théorie quand même…

Était-ce utile?

La solution

Malheureusement, un composant COM est chargé dans Process Space et non dans le contexte d'un AppDomain. Ainsi, vous devrez supprimer manuellement (libérer et décharger) vos DLL natives (s'applique à la fois à COM et à P / Invoke). Détruire simplement un domaine d'application ne vous sera d'aucune utilité, mais il ne devrait pas être nécessaire de rétablir l'ensemble du processus pour réinitialiser l'état COM (recréer simplement le ou les objets COM devrait également fonctionner normalement, cela ressemble à un bogue dans le code du fournisseur du composant, peut-être ils peuvent y remédier?)

Références

Espace d'adressage de processus (TechNet)

Domaines d'application (MSDN)

Limites (MSDN): processus et AppDomains

Autres conseils

Voici la preuve que la réponse de Shaun Wilson est correcte

Domaine de l

Ne créez pas votre contrôleur MBR. Créez un petit proxy qui charge le contrôleur dans le deuxième domaine et le démarre. De cette façon, les dll du contrôleur ne seront pas chargées dans le premier domaine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top