Question

je dois utiliser des appels entre domaines d'application dans mon application, et parfois je cette RemotingException:

Object « /2fa53226_da41_42ba_b185_ec7d9c454712/ygiw+xfegmkhdinj7g2kpkhc_7.rem » a été déconnecté ou n'existe pas au niveau du serveur.

L'objet cible est encore en vie, je l'ai vérifié.

UPD I AVONS point d'arrêt de jeu dans le finaliseur de l'objet cible, et il frappe jamais. Ainsi, cet objet est vivant et n'a pas été GC'ed.

Était-ce utile?

La solution

C'est probablement parce que le garbage collector locale du côté serveur recueille l'objet. Vous pouvez empêcher que, en renouvelant la location. Vous pouvez en lire plus à ce sujet dans ces articles:

Mise à jour : Malheureusement, les problèmes MSDN Magazine de 2008 ou plus ne sont plus browseable en ligne, mais seulement sous forme de fichiers .chm que vous devez télécharger sur votre machine locale. Les anciens numéros se trouvent dans:

Autres conseils

En effet, la gestion de la vie sur le côté serveur déconnecte l'objet lorsque son bail expire, pour permettre GC pour les recueillir. Si vous essayez de l'utiliser à partir du côté client, vous obtiendrez une exception, même si elle n'a pas été GC'd sur le serveur encore (par exemple parce qu'il ya encore une autre référence à), mais le bail a expiré. Ceci permet d'éviter un comportement imprévisible. La réponse acceptée fournit une bonne référence sur la façon de gérer correctement la durée de vie des objets .NET à distance.

J'ai eu le même problème et j'ai cherché pendant de nombreuses heures avec l'aide de nombreux postes stackoverflow.

Je trouve enfin la question complète.

  1. Je dois utiliser un commanditaire pour maintenir ma vie MarshalByRefObject.
  2. J'ai eu alors le même problème que @ user626528: objet est vivant mais j'avais l'exception. En fait, Je avais besoin de "parrain" TOUS LES " TransparentProxy " cas , et non seulement le principal: mon principal objet créé en SandBox (un autre AppDomain) renvoie des références à d'autres MarshalByRefObjects.

Voici l'explication complète et cas d'utilisation:

Ma classe « Loader » hérite de MarshalByRefObject, et je le garder en vie avec une classe iSponsor. Je sais que « ClientSponsor » existe dans .NET, mais je n'avais aucun moyen de déterminer si et lorsque le renouvellement () est appelée, donc je fait ma classe avec l'aide de la communauté StackOverflow (commentaires du code de lecture):

/// <see cref="https://stackoverflow.com/questions/18680664/remoting-sponsor-stops-being-called"/>
public class RemotingSponsor : MarshalByRefObject, ISponsor, IDisposable
{
    /*
     * @CoryNelson said :
     * I've since determined that the ILease objects of my sponsors 
     * themselves are being GCed. They start out with the default 5min lease 
     * time, which explains how often my sponsors are being called. When I 
     * set my InitialLeaseTime to 1min, the ILease objects are continually        
     * renewed due to their RenewOnCallTime being the default of 2min.
     * 
     */ 

    ILease _lease;

    public RemotingSponsor(MarshalByRefObject mbro)
    {
        _lease = (ILease)RemotingServices.GetLifetimeService(mbro);
        if (_lease == null) throw new NotSupportedException("Lease instance for MarshalByRefObject is NULL");
        _lease.Register(this);
    }

    public TimeSpan Renewal(ILease lease)
    {
        Debug.WriteLine("RemotingSponsor.Renewal called");
        return this._lease != null ? lease.InitialLeaseTime : TimeSpan.Zero;
    }


    public void Dispose()
    {
        if (_lease != null)
        {
            _lease.Unregister(this);
            _lease = null;
        }
    }

    public override object InitializeLifetimeService()
    {
        /*
         *
         * @MatthewLee said:
         *   It's been a long time since this question was asked, but I ran into this today and after a couple hours, I figured it out. 
         * The 5 minutes issue is because your Sponsor which has to inherit from MarshalByRefObject also has an associated lease. 
         * It's created in your Client domain and your Host domain has a proxy to the reference in your Client domain. 
         * This expires after the default 5 minutes unless you override the InitializeLifetimeService() method in your Sponsor class or this sponsor has its own sponsor keeping it from expiring.
         *   Funnily enough, I overcame this by returning Null in the sponsor's InitializeLifetimeService() override to give it an infinite timespan lease, and I created my ISponsor implementation to remove that in a Host MBRO.
         * Source: https://stackoverflow.com/questions/18680664/remoting-sponsor-stops-being-called
        */
        return (null);
    }
}

Et puis je ce « parrain personnalisé » comme ceci:

// Loader and Container for MarshalByRefObject in another domain
 public class PluginFile : IDisposable
 {
           private RemotingSponsor _sponsor; // Keep instance not to have Sponsor Garbage Collected
           private AppDomain _sandbox;
           private ICustomPlugin[] _plugins; // I do not store real instances of Plugins, but a "CustomPluginProxy" which is known both by main AppDomain and Plugin AppDomain.

    // Constructor : load an assembly file in another AppDomain (sandbox)
    public PluginFile(System.IO.FileInfo f, AppDomainSetup appDomainSetup, Evidence evidence)
    {
        Directory = System.IO.Path.GetDirectoryName(f.FullName) + @"\";
        _sandbox = AppDomain.CreateDomain("sandbox_" + Guid.NewGuid(), evidence, appDomainSetup);

        _sandbox.Load(typeof(Loader).Assembly.FullName);

        // - Instanciate class "Loader" INSIDE OTHER APPDOMAIN, so we couldn't use new() which would create in main AppDomain.
        _loader = (Loader)Activator.CreateInstance(
            _sandbox,
            typeof(Loader).Assembly.FullName,
            typeof(Loader).FullName,
            false,
            BindingFlags.Public | BindingFlags.Instance,
            null,
            null,
            null,
            null).Unwrap();

        // - Load plugins list for assembly
        _plugins= _loader.LoadPlugins(f.FullName); 


        // - Keep object created in other AppDomain not to be "Garbage Collected". I create a sponsor. The sponsor in registed for object "Lease". The LeaseManager will check lease expiration, and call sponsor. Sponsor can decide to renew lease. I not renewed, the object is garbage collected.
        // - Here is an explanation. Source: https://stackoverflow.com/questions/12306497/how-do-the-isponsor-and-ilease-interfaces-work
        _sponsor = new RemotingSponsor(_loader);

       // Here is my SOLUTION after many hours ! I had to sponsor each MarshalByRefObject (plugins) and not only the main one that contains others !!!
       foreach (ICustomPlugin plugin in Plugins) 
        {
            ILease lease = (ILease)RemotingServices.GetLifetimeService((PluginProxy)plugin);
            lease.Register(_sponsor); // Use the same sponsor. Each Object lease could have as many sponsors as needed, and each sponsor could be registered in many Leases.
        }
    }

 }

Le type PluginProxy a une référence vers le type réel de plug-in. En effet, le PluginProxy est instancié dans Plugin AppDomain, et est revenu à principal AppDomain, pour lui permettre d'appeler Plugins même si elle ignorer leur type réel. Ainsi, le PluginProxy, être accessible à partir principale AppDomain, doivent être sérialisé à des limites transversales de domaines d'application. J'ai eu un problème parce que je ne les a parrainés MarshalByRefObject (s):

 /// <see cref="https://stackoverflow.com/questions/4185816/how-to-pass-an-unknown-type-between-two-net-appdomains"/>
    [Serializable]
    public class PluginProxy : MarshalByRefObject, ICustomPlugin
    {
        private ICustomPlugin _hostedPlugin;            

        /// <summary>
        /// Parameterless constructor for deserialization 
        /// </summary>
        public PluginProxy()
        {             
        }

        ~PluginProxy()
        {
            Debug.WriteLine("DESTRUCTOR ~PluginProxy");
        }

        /// <summary>
        /// Constructor reserved from real Plugin type
        /// </summary>
        /// <param name="name"></param>
        public PluginProxy(ICustomPlugin hostedPlugin)
        {
            _hostedPlugin = hostedPlugin;
        }

        public PluginName Name => _hostedPlugin.Name;

        public PluginResult Execute(PluginParameters parameters, PluginQuery query)
        {
            return(_hostedPlugin.Execute(parameters, query));
        }
    }

Il était un groupe difficile de problèmes à résoudre, espérons que cette aide!

Références:

Cela est arrivé pour nous parce que nous avions une variable statique dans l'une de nos classes qui était de type AppDomain. La classe a été utilisé dans un service de longues fenêtres en cours d'exécution. AppDomain a une méthode InitializeLifetimeService qui doit être redéfinie comme ceci:

public override object InitializeLifetimeService(){
    return null;
}

Nous avons été constamment en utilisant cela comme la variable privée chargé et déchargé des dll pour l'extérieur sur mesure logique. La réponse a été prise d'ici: msdn réponse

Parce que nous n'avons pas pu changer cela au moment de la production, nous avons fini avec un compromis de redémarrer le service Windows à des intervalles aléatoires qui sont plus courtes que la durée de vie de la variable AppDomain statique qui, par essais et erreurs nous avons constaté qu'il est plusieurs jours.

Cette question a également permis de clarifier certaines choses sur la vie: stackoverflow -Question

dans mon cas, le problème est que, dans l'ordinateur client, il y a un adaptateur de réseau virtuel actif, la désactivation des adaptateurs de réseau virtuel, le problème a été résolu

Dans mon cas, cela se passait avec LocalDB SQL stocké dans le dossier App_Data intérieur projet Web. Chaque fois que je tente d'utiliser la console package pour exécuter update-database init ma base de données Entity Framework en utilisant les migrations, rien ne se passe. Puis, après un certain temps, je reçois cette erreur.

Je résolu ce problème en révisant les autorisations de fichiers sur App_Data. Une fois fixé, le tour est joué, il a travaillé.

Cette question a été répondu en grand détail déjà sur StackOverflow . TL / DR:

  1. Si vous voulez que override Singleton InitializeLifetimeService retourne nULL
  2. Utiliser
scroll top