2010-02-19 3 views
8

У меня возникли проблемы с выяснением чего-то из моего звонка AppDomain.Unload(...). У меня есть подробное объяснение с кодом от my earlier question. Как оказалось, я выполнял пару шагов, которые, по-видимому, мне не нужны. Тем не менее, я абсолютно уверен, что, когда AppDomain создается, а затем провел в коллекции:AppDomain Разгрузочное убийство Parent AppDomain

private static Dictionary<string , AppDomain> 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. Мне интересно, не ссылается ли эта ссылка на Start() модуля IModule (который реализует сборка модуля плагина) неправильно (из-за моей реализации). Итак, когда вызывается метод Shutdown(), все приложение умирает. Должен ли я сделать свой 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. Поэтому, когда я пытаюсь выгрузить дочерний домен, оба домена выгружаются. Правильно ли это? И что, вероятно, будет лучшим решением для обеспечения методов Start() & Stop() через объект MBR (адаптер)?

UPDATE: см мой ответ ниже изменения -
Хорошо, что нет утечки - все наследует MBR:

  1. Ведущий: MarshalByRefObject - все вхождения в ModuleAdapter в новом AppDomain
  2. ModuleAdapter : MarshalByRefObject - IModule интерфейс, методы интерфейса (Пуск, Стоп)
  3. MyModulePlugin: MarshalByRefObject - Application.Run (Myform)

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

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

+0

Я предполагаю, что это связано с тем, что вы начинаете winform в дочернем домене ... Почему бы вам не начать winform в домене по умолчанию. Я думаю, что после выхода основного потока пользовательского интерфейса приложение закончится. Посмотрите на блог raymond chen. – Fakrudeen

+0

@Fakrudeen: Я бы хотел посмотреть блог без поиска ... у вас есть ссылка? ;) – IAbstract

+0

Обязательно подключитесь к AppDomain.CurrentDomain.UnhandledExceptionHandler, чтобы проверить, что срывает ваш домен. –

ответ

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

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

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