IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Dotnet Discussion :

Cycles de vie des AppDomains et MBRO en local (interprocessus)


Sujet :

Dotnet

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut Cycles de vie des AppDomains et MBRO en local (interprocessus)
    Bonjour à tous. Je connais assez peu les AppDomains et je me suis retrouvé aujourd'hui face à plusieurs questions restées sans réponses malgré des heures passées sur Google et MSDN. Toute aide serait donc la bienvenue.


    Problème
    Je développe une biblio qui doit à un moment générer et charger des assemblys au sein d'un AppDomain isolé (sandbox/bac à sable). Un singleton est créé côté bac à sable, un délégué invoque une méthode du Singleton côté parent.

    [Parent] void func(int) possède un proxy vers [Sandbox] Singleton.Instance.Run(int)

    Jusque là, tout va bien. Mais ces bacs à sables doivent être détruits (AppDomain.Unload) par la suite, de façon non-déterministe, lorsque les références aux délégués générés ont été perdues par le parent. Et les MBRO associés doivent être maintenus en vie avant cela.


    Ce que je crois savoir...
    De ce que j'ai cru comprendre, dans le cas d'AppDomains confinés au sein du même processus (même machine), les règles sont les suivantes. Pouvez infirmer ou confirmer s'il vous plaît ?
    1. Le MBRO (MarshalByRefObject) côté sandbox et son proxy côté parent ont une durée de vie totalement indépendante l'une de l'autre.
    2. Le MBRO est détruit automatiquement une fois son bail expiré (le ILease généré par InitializeLifeTimeService), même si le proxy existe toujours côté parent.
    3. InitializeLifeTimeService est invoqué automatiquement (après la création de l'objet ?), pas besoin de l'appeler explicitement. Mais c'est nécessaire si l'on veut change le bail (ILease) renvoyé par défaut.
    4. Le proxy côté parent est soumis aux règles normales du ramasse-miettes : il est détruit lorsque toutes les références vers lui ont été perdues, même si le MBRO existe toujours côté bac à sable.
    5. Un AppDomain n'est jamais automatiquement détruit (sauf fin du processus, surcharge mémoire, etc), il doit donc l'être explicitement via AppDomain.Unload.
    6. Puis-je utiliser le bail renvoyé par AppDomain.InitializeLifeTimeService() en lieu et place de AppDomain.Unload ? Et est-ce conseillé ?


    Première solution foireuse
    Pour chaque AppDomain, un objet AppDomainTracker garde des WeakReference sur tous les délégués/proxies créés. Une fois par minute, un thread se réveille et vérifie si toutes les références sont mortes (les proxies associés ne sont plus référencés par "parent"). Si c'est le cas, AppDomain.Unload est appelé.

    Ça ne gardait par les MBRO en vie mais ça permettait de nettoyer l'AppDomain une fois devenu inutile. Problème : l'utilisation de AppDomain.Unload dans un autre thread que le principal a des conséquences étranges. Au pire l'application est bloquée (pas de pb de deadlock ou autre, ça bloque ailleurs que dans mon code), au mieux elle ne l'est pas mais le thread associé aux AppDomainTrackers n'est jamais terminé (alors qu'il n'est pas bloqué et fonctionne normalement, je peux continuer à le déboguer, il n'a simplement jamais reçu de ThreadAbortException et continue à être réveillé toutes les 60s).


    Solution envisagée
    Ayant appris à me méfier de AppDomain.Unload depuis un thread perso et venant à comprendre que je devais aussi veiller à garder les MBRO en vie, je me suis dit que le mieux était de faire de AppDomainTracker un sponsor (ISponsor) de baux (leases) : chaque fois qu'un MBRO demande le renouvellement de son partenariat (sponsorship), les WeakReferences sont vérifiées et l'AppDomain détruit si toutes les références sont mortes. J'ignore sur quel thread (le GC ?) cela se fera exactement mais mon petit doigt me dit que je n'aurais pas les mêmes problèmes qu'auparavant.

    N'étant pas sûr de bien comprendre le fonctionnement du bouzin, je me tourne vers vous. Cela peut-il fonctionner ? Ou suis-je à côté de la plaque ? Merci d'avance à ceux qui voudront bien me donner un peu de leur temps.

  2. #2
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    J'ai résolu tout ça. Au cas où quelqu'un passerait par là avec les mêmes questions...

    * Le système de baux n'est pas du tout utilisé pour deux domaines situés dans le même processus : le MBRO a une vie dépendante de celle du proxy ont une et relève des règles normales du GC, comme le serait un objet référencé par un autre.

    * L'utilisation d'un thread est la bonne, il faut simplement faire attention aux éventuels blocs catch/finally : si un AppDomain est déchargé (unload) dans un tel bloc, il existe quelques bugs.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 21/06/2012, 13h08
  2. Réponses: 17
    Dernier message: 13/09/2011, 16h53
  3. Réponses: 0
    Dernier message: 19/04/2011, 11h56
  4. ASP.Net : Cycle de vie des données affichées
    Par chaillom dans le forum Développement Web avec .NET
    Réponses: 3
    Dernier message: 16/03/2010, 14h17
  5. Cycle de vie des classes Action ?
    Par guillaume06 dans le forum Struts 1
    Réponses: 3
    Dernier message: 04/10/2007, 10h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo