AppDomain Разгружают Родителя уничтожения AppDomain

Я испытываю затруднения при понимании чего-то о моем AppDomain.Unload(...) звонить. У меня есть подробное объяснение с кодом от моего более раннего вопроса. Как оказалось, я выполнял несколько шагов, что, по-видимому, я не должен. Однако я вполне уверен что, когда AppDomain создан и затем сохранен в наборе:

private static Dictionary HostDomains;

void StartNewDomain(string domainName)
{
    AppDomain domain = AppDomain.CreateDomain(domainName);
    HostDomains[domainName] = domain;
}

... когда Вы сделаны с ним, необходимо разгрузить его:

if (HostDomains.ContainsKey(domainName))
{
    AppDomain.Unload(HostDomains[domainName]);
    HostDomains.Remove(domainName);
}

затем удалите домен из набора.

Когда я разгружаю домен, однако, целое приложение заканчивается. Если я удаляю разгружение, все хорошо..., и нас просто оставляют с удалением домена от набора. Но я боюсь, что мой дочерний AppDomain действительно не разгружен. Это может в конечном счете получить GC'd, который я предполагаю, но это не дает мне теплое нечеткое.

Дочерний блок AppDomain (приложение Windows Form) запускается асинхронно через интерфейс (IModule), на который ссылаются в моем классе адаптера, который наследовался MarshalByRefObject. Я задаюсь вопросом, не упорядочивает ли эта ссылка на Запуск IMODULE () (который реализует сменная модульная конструкция) правильно (из-за моей реализации). Так, когда Завершение работы () метод называют, целое приложение умирает. Я должен сделать свой IModule абстрактным классом вместо этого, таким образом, он должен наследовать MBR также? Озадаченный...

После рассмотрения моего кода:

// instances the module for access to the module's Start() method
    IModule module = (IModule)domain.CreateInstanceAndUnwrap(
    ModuleManager.Modules[modName].Name, 
    ModuleManager.Modules[modName].EntryPoint.FullName);

... мой страх состоит в том, что, так как IModule является интерфейсом, даже при том, что я создаю экземпляр в дочернем домене, блок просачивается в мой основной AppDomain. Поэтому, когда я пытаюсь разгрузить дочерний домен, оба домена разгружаются. Это было бы корректно? И каково, вероятно, было бы лучшее решение обеспечить, Запускаются () и Остановка () методы через MBR (адаптер) объект?

ОБНОВЛЕНИЕ: см. мой ответ ниже для изменений-
Хорошо, нет никакой утечки - все наследовало MBR:

  1. Хост: MarshalByRefObject - инстанцирует ModuleAdapter в новом AppDomain
  2. ModuleAdapter: интерфейс MarshalByRefObject - IModule, методы интерфейса (Запускаются, Остановка),
  3. MyModulePlugin: MarshalByRefObject - приложение. Выполненный (myForm)

Я делаю что-то не так все еще? Я попробовал несколько вещей, и это просто, кажется, неправильно или неполно. Когда я говорю ModuleAdapter завершать работу, он звонит AppDomain.Unload(AppDomain.CurrentDomain) и домен Host останавливается также. Я все еще получаю некоторые первые случайные исключения на выходе приложения. Но форма (myForm) была сказана.Close ().

Так, я все еще ищу корректный способ сделать это...

8
задан Community 23 May 2017 в 11:58
поделиться

1 ответ

Как я и подозревал, создание экземпляра с интерфейсом IModule в основном домене вызывает утечку. Чтобы сделать это правильно:

AppDomain domain = AppDomain.CreateDomain(domainName);
HostDomains[domainName] = domain;  // put in collection

ModuleAdapter adapter = (ModuleAdapter)domain.CreateInstanceAndUnwrap(asmName , typeName);

где ModuleAdapter наследует MarshalByRefObject . Затем:

adapter.Execute(moduleAssembly , moduleType);

Внутри класса ModuleAdapter:

public void Execute(string Name, string EntryPoint)
{
    module  = (IModule)AppDomain.CurrentDomain.CreateInstanceAndUnwrap(Name , EntryPoint);
}

Я приветствую комментарии или дополнительные ответы для лучшего способа.

После перемещения экземпляра в класс ModuleAdapter у нас все еще есть проблема с AppDomain.Unload, убивающая все приложение. Мне было интересно, связано ли это с тем, что в плагине модуля мы используем Application.Run (myForm) - тогда, когда мы завершаем работу, мы вызываем myForm.Close (). Очевидно, это завершает работу приложения, поэтому мне было интересно, «выгружает» ли myForm.Close () также AppDomain.

1
ответ дан 6 December 2019 в 02:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: