AppDomain卸载杀死父AppDomain

IAb*_*act 8 c# appdomain .net-3.5

我无法搞清楚我的AppDomain.Unload(...)电话.我用我之前的问题中的代码详细解释了一下.事实证明,我执行了几个步骤,显然,我不需要.但是,我很确定在创建AppDomain并将其保存在集合中时:

private static Dictionary<string , AppDomain> HostDomains;

void StartNewDomain(string domainName)
{
    AppDomain domain = AppDomain.CreateDomain(domainName);
    HostDomains[domainName] = domain;
}
Run Code Online (Sandbox Code Playgroud)

......当你完成它之后,你必须卸载它:

if (HostDomains.ContainsKey(domainName))
{
    AppDomain.Unload(HostDomains[domainName]);
    HostDomains.Remove(domainName);
}
Run Code Online (Sandbox Code Playgroud)

然后从集合中删除域.

但是,当我卸载域时,整个应用程序正在结束.如果我删除卸载,一切都很好......我们只是从集合中删除域.但我担心我的孩子AppDomain 没有真正卸载.它可能最终得到GC我猜,但这并没有给我一个温暖的模糊.

子AppDomain程序集(Windows窗体应用程序)通过我继承的适配器类中引用的接口(IModule)异步启动MarshalByRefObject.我想知道这个对IModule的Start()(插件模块程序集实现的)的引用是不是正确编组(因为我的实现).因此,当调用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);
Run Code Online (Sandbox Code Playgroud)

...我担心,因为IModule是一个接口,即使我在子域中创建一个实例,程序集也会泄漏到我的主AppDomain中.因此,当我尝试卸载子域时,两个域都被卸载.这是正确的吗?什么可能是通过MBR(适配器)对象提供Start()和Stop()方法的最佳解决方案?

更新:请参阅下面的答案进行更改 -
好的,没有泄漏 - 一切都继承了MBR:

  1. 主机:MarshalByRefObject - 在新的AppDomain中实例化ModuleAdapter
  2. ModuleAdapter:MarshalByRefObject - IModule接口,接口方法(Start,Stop)
  3. MyModulePlugin:MarshalByRefObject - Application.Run(myForm)

我还做错了吗?我尝试了几件事情,但这似乎是错误的或不完整的.当我告诉ModuleAdapter关闭时,它会调用AppDomain.Unload(AppDomain.CurrentDomain)并且Host域也会停止.我仍然在应用程序退出时获得一些第一次机会异常.但是形式(myForm)已被告知.Close().

所以,我仍在寻找正确的方法......

IAb*_*act 1

正如我怀疑的那样,在主域中实例化 IModule 接口会导致泄漏。为了正确执行此操作:

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

ModuleAdapter adapter = (ModuleAdapter)domain.CreateInstanceAndUnwrap(asmName , typeName);
Run Code Online (Sandbox Code Playgroud)

其中 ModuleAdapter 继承MarshalByRefObject. 然后:

adapter.Execute(moduleAssembly , moduleType);
Run Code Online (Sandbox Code Playgroud)

ModuleAdapter 类内部:

public void Execute(string Name, string EntryPoint)
{
    module  = (IModule)AppDomain.CurrentDomain.CreateInstanceAndUnwrap(Name , EntryPoint);
}
Run Code Online (Sandbox Code Playgroud)

我欢迎评论或其他答案以获得更好的方法。

将实例移至 ModuleAdapter 类后,我们仍然遇到 AppDomain.Unload 杀死整个应用程序的问题。我想知道这是否是因为在我们正在使用的模块插件中Application.Run(myForm)- 然后当我们关闭时我们调用 myForm.Close()。显然这会关闭应用程序,所以我想知道 myForm.Close() 是否也会“卸载”AppDomain。