«Объект был отключен или не существует на сервере».

StackOverflow https://stackoverflow.com/questions/6339469

Вопрос

Мне нужно использовать перекрестные вызовы в моем приложении, и иногда у меня есть это удаленное экспрессию:

Object '/2FA53226_DA41_42BA_B185_EC7D9C454712/YGIW+XFEGMKHDINJ7G2KPKHC_7.REM' был отключен или не существует на сервере.

Целевой объект все еще жив, я проверил его.

UPD Я установил точку останова в финализаторах целевого объекта, и он никогда не попадает. Таким образом, этот объект жив и не был GC'ed.

Это было полезно?

Решение

Вероятно, это потому, что локальный сборщик мусора на стороне сервера собирает объект. Вы можете предотвратить это, обновляя лизинг. Вы можете прочитать больше об этом в этих статьях:

Обновлять: К сожалению, проблемы с журналом MSDN с 2008 года или старше больше не доступны в Интернете, а только как файлы .CHM, которые вы должны загрузить на свою локальную машину. Предыдущие проблемы можно найти в:

Другие советы

Это связано с тем, что управление сроком службы на стороне сервера отключает объект, когда его аренда истекает, чтобы GC собирал его. Если вы попытаетесь использовать его со стороны клиента, вы получите исключение, даже если оно еще не было GC'd на сервере (например, потому что на него все еще есть еще одна ссылка), но срок аренды истек. Это следует избегать непредсказуемого поведения. Принятый ответ дает хорошую ссылку о том, как правильно управлять сроком службы удаленных объектов .NET.

У меня была та же проблема, и я искал много часов с помощью многих сообщений Stackoverflow.

Я наконец нашел полную проблему.

  1. Я должен использовать спонсора, чтобы поддерживать свой Marshalbyrefobject живым.
  2. Затем у меня была та же проблема, что и @user626528: объект жив, но у меня было исключение. Фактически, Мне нужно было «спонсировать» все »Прозрачный пророк"Случай, и не только основной: мой основной объект, созданный в песочнице (другой приложение), возвращает ссылки на другие маршалбирефобъекты.

Вот полный вариант объяснения и использования:

Мой класс «погрузчик» наследует от Marshalbyrefobject, и я поддерживаю его в классе Isponsor. Я знаю, что «клиентпонсор» существует в .NET, но у меня не было возможности определить, называется ли и когда renreadal (), поэтому я сделал свой класс с помощью сообщества StackOverflow (читать комментарии кода):

/// <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);
    }
}

А потом я использовал этот «пользовательский спонсор», как это:

// 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.
        }
    }

 }

Тип PlaginProxy имеет ссылку на реальный тип плагина. Действительно, плагинпроток инстацнузируется внутри Appdomain и возвращается в основной приложение, чтобы позволить ему вызовать плагины, даже если он игнорирует их реальный тип. Таким образом, плагинпрокси, доступный из основного приложения, должен быть сериализован для пересечения ограничений приложений. У меня была проблема, потому что я не спонсировал эти Marshalbyrefobject (ы):

 /// <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));
        }
    }

Это была сложная группа проблем, надеюсь, это поможет!

Использованная литература:

Это произошло для нас, потому что у нас была статическая переменная в одном из наших классов, которая была типа Appdomain. Класс использовался в долгосрочной службе Windows. У Appdomain есть метод инициализации, который должен быть переопределен, как это:

public override object InitializeLifetimeService(){
    return null;
}

Мы постоянно использовали это в качестве частной переменной, которая загружала и разгружала несколько DLL для индивидуальной построенной внешней логики. Ответ был взят отсюда: MSDN Ответ

Поскольку мы не смогли изменить это во время производства, мы закончили компромисс перезагрузки службы Windows с помощью случайных промежутков, которые короче срока службы статической переменной Appdomain, которые по испытанию и ошибке мы обнаружили, что это несколько дней.

Этот вопрос также помог прояснить некоторые вещи о жизни: stackoverflow-Question

В моем случае проблема заключалась в том, что на клиентском компьютере был активный адаптер виртуального сети, отключающий адаптеры виртуальных сети, проблема была решена

В моем случае это происходило с SQL Localdb, хранящимся в App_Data папка внутри Web проект. Всякий раз, когда я пытаюсь использовать консоль пакета для запуска update-database Чтобы инициировать мою базу данных Ontity Framework, используя миграции, ничего не происходит. Затем через некоторое время я получаю эту ошибку.

Я решил это, пересмотрев разрешения на файлы на App_Data. Анкет После исправления, вуаля, это сработало.

Этот вопрос был Ответ в отличном ответе уже на Stackoverflow. Анкет TL/DR:

  1. Если вы хотите переопределить Singleton Semantics InitializeLifetimeService Чтобы вернуть ноль
  2. Использовать ClientSponsor чтобы держать вас в живых дольше.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top