Срок службы C# объекта Assembly, созданного интерфейсом с Activator.CreateInstance - PullRequest
0 голосов
/ 29 мая 2020

Я экспериментирую с архитектурой плагина, используя C# и делаю tnet. Я обнаружил, что любой экземпляр, созданный таким образом, не собирается до закрытия приложения.

Моя первоначальная мысль заключалась в том, чтобы загрузить каждый объект и вызвать метод регистрации, а затем разрешить ему d ie. Метод регистрации будет передавать обратно информацию, необходимую, чтобы знать, когда он должен быть загружен в будущем, и в это время создает новый экземпляр. Это помешало бы мне сохранить в живых около 50 объектов, когда они не используются. любые предметы. Только когда я закрываю приложение, происходят какие-либо вызовы финализатора. Если я провожу эксперимент, в котором у меня есть внутренний экземпляр IProduct, и загружаю в него несколько экземпляров, я получаю 5 вызовов конструктора и как только закрываю 5 вызовов финализатора. интерфейс. Итак, я получаю вызов конструктора Class1 и вызов конструктора Class2. Но получить вызовы деструктора только при закрытии. . Это сокращено, чтобы данные из загруженной библиотеки DLL не передавались в основную программу, чтобы гарантировать, что я не сохраню ничего живого из-за зависания ссылки, но я все еще вижу те же результаты.

    void LoadProductPlugins()
    {
        string[] sFiles = Directory.GetFiles(Directory.GetCurrentDirectory() + "\\dll", "*.dll", SearchOption.TopDirectoryOnly);

        foreach (string strDll in sFiles)
        {
            Assembly assy = Assembly.LoadFile(strDll);

            Type[] types = (from t in assy.GetExportedTypes()
                                 where !t.IsInterface && !t.IsAbstract
                                 where typeof(IProduct).IsAssignableFrom(t)
                                 select t).ToArray();
            for (int i = 0; i < types.Length; i++)
            {
                IProduct myDLL = (IProduct) Activator.CreateInstance(types[i]);
            }
        }
    }

1 Ответ

1 голос
/ 29 мая 2020

Нет никакой разницы в управлении продолжительностью жизни объекта, независимо от того, создан ли он с помощью обычного new, CreateInstance или любого другого метода, который можно придумать. Объект будет собираться, когда требуется G C и конкретный объект больше недоступен.

Примечания:

  • Финализаторы вызываются только как часть полного G C пройти (Gen 2). Это приводит к поведению, которое вы видите, когда финализаторы вызываются при завершении работы только потому, что недостаточно памяти для использования G C ранее.
  • Сами сборки не выгружаются, пока не будет выгружен AppDomain. Если вы не создаете отдельный AppDomain для своих плагинов, это означает, что сборка не будет выгружена. Вы можете прочитать о загрузке сборки / управлении версиями - чтение всех сообщений около https://docs.microsoft.com/en-us/archive/blogs/suzcook/assembly-identity сэкономит вам много времени.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...