2010-08-27 7 views
2

J'ai une application qui utilise des plugins. Je charge les plugins dans un autre domaine. J'utilise la classe RemoteHandle de http://www.pocketsilicon.com/post/Things-That-Make-My-Life-Hell-Part-1-App-Domains.aspx pour empêcher que l'objet soit collecté après 5 minutes.Annuler l'inscription Lease throws InvalidOperationException

Cela fonctionne très bien aussi longtemps que ma demande est en cours d'exécution, mais quand il est en cours d'arrêt i obtenir un InvalidOperationException lorsque Désenregistrement

internal static void Unregister(MarshalByRefObject value) 
    { 
     if (value != null && RemotingServices.IsTransparentProxy(value)) 
     { 
      lock (_syncLock) 
      { 
       ReferencedLease r; 
       if (_leaseReferences.TryGetValue(value, out r) && --r.ReferenceCount <= 0) 
       { 
        // Note: Dictionary clears key and value from bucket list upon remove. 
        _leaseReferences.Remove(value); 
        r.Lease.Unregister(_instance); // <----- Here i get the exception 

       } 
      } 
     } 
    } 

Stacktrace:

System.InvalidOperationException: Handle is not initialized. 
    at System.WeakReference.set_Target(Object value) 
    at System.Runtime.Remoting.IdentityHolder.SetIdentity(Identity idObj, String URI, DuplicateIdentityOption duplicateOption) 
    at System.Runtime.Remoting.IdentityHolder.FindOrCreateIdentity(String objURI, String URL, ObjRef objectRef) 
    at System.Runtime.Remoting.RemotingServices.InternalUnmarshal(ObjRef objectRef, Object proxy, Boolean fRefine) 
    at System.Runtime.Remoting.ObjRef.GetRealObjectHelper() 
    at System.Runtime.Remoting.Lifetime.ILease.Unregister(ISponsor obj) 
    at Quick3PlugInManager.Sponsor.Unregister(MarshalByRefObject value) 
    at Quick3PlugInManager.RemoteHandle`1.Dispose(Boolean disposing) 
    at Quick3PlugInManager.RemoteHandle`1.Finalize() 

Pourquoi ai-je cette exception?

Répondre

1

Je m'abonne à l'événement Unload des domaines d'application et je vérifie si le domaine d'application a déjà été déchargé. Si c'est le cas, alors je soupçonne que vous n'avez plus besoin de désenregistrer ce handle (avalez juste l'exception) parce que le CLR l'a fait pour vous. Ceci est juste une théorie, mais cela pourrait vous donner plus d'informations.

+0

C'est exact. Le domaine est déchargé et puis j'essaye de disposer le prochain plugin ... Puis-je placer les deux comme acceptés? – klundby

+0

Je suis certain que vous ne pouvez en marquer qu'un comme accepté. –

1

Vous obtenez cette exception car le code est en cours d'exécution dans le thread du finaliseur. Vous faites référence à un objet déjà finalisé. L'ordre dans lequel les objets sont finalisés n'est pas déterministe.

C'est ce qui le cause, ce que vous feriez à ce sujet n'est pas clair pour moi de l'extrait.

+0

C'est exact. Le domaine est déchargé et puis j'essaye de disposer le prochain plugin ... Puis-je placer les deux comme acceptés? – klundby

3

J'ai écrit le message original sur Pocket Silicon. Nous avons également eu cette question et notre travail actuel consiste à prendre des exceptions ici. J'aimerais trouver un moyen de savoir si le domaine étranger est toujours en vie mais n'en a pas trouvé un (oui, je pourrais avoir ce domaine me dire quand il s'en va, mais je ne veux pas d'exigences supplémentaires placées sur les objets distants).

Voici le bloc catch que nous utilisons actuellement:

try 
    { 
     // Catch here -- if we are finalizing we may have already 
     // finalized the weak handle in the table or the lease may 
     // have already been unloaded. 
     r.Lease.Unregister(Sponsor.instance); 
    } 
    catch (InvalidOperationException) { } 
    catch (AppDomainUnloadedException) { } 

Je vais mettre à jour le poste.

Questions connexes