2010-02-19 64 views
8

我无法找到关于我的AppDomain.Unload(...)调用的信息。我对my earlier question的代码有详细的解释。事实证明,我正在执行几个步骤,显然,我不需要。不过,我相当肯定,被创建,然后一个AppDomain在集合地点及时间: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,但这并没有给我一个温暖的模糊。

通过继承MarshalByRefObject的适配器类中引用的接口(IModule)异步启动子AppDomain程序集(Windows窗体应用程序)。我想知道是否对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); 

...我担心的是,因为IModule的是一个接口,即使我在子域中创建一个实例,该组件泄漏进入我的主AppDomain。因此,当我尝试卸载子域时,两个域都将被卸载。这是正确的吗?通过MBR(适配器)对象提供Start()& Stop()方法可能是最佳解决方案?

更新:看到我的回答如下更改 -
好吧,有没有泄漏 - 一切都继承了MBR:

  1. 主持人:MarshalByRefObject的 - 实例ModuleAdapter在新的AppDomain
  2. ModuleAdapter :MarshalByRefObject的 - 的IModule接口,接口方式(启动,停止)
  3. MyModulePlugin:MarshalByRefObject的 - Application.Run(myForm的)

我还在做错什么?我已经尝试了几件事情,但似乎是错误的或不完整的。当我告诉ModuleAdapter关闭时,它会调用AppDomain.Unload(AppDomain.CurrentDomain)并且主机域也会停止。我仍然在应用程序出口获得一些第一次机会例外。但是窗体(myForm)被告知.Close()。

所以,我仍然在寻找这样做的正确方法...

+0

我的猜测是它与你在儿童appdomain中启动winform有关......你为什么不在默认域中启动winform。我想一旦UI主线程退出应用程序将结束。看看雷蒙德的博客。 – Fakrudeen 2010-02-19 09:24:59

+0

@Fakrudeen:我想在没有搜索的情况下查看博客...你有链接吗? ;) – IAbstract 2010-02-19 22:45:12

+0

一定要连接到AppDomain.CurrentDomain.UnhandledExceptionHandler,以检查是否有什么撕裂你的域名。 – 2011-10-27 11:26:35

回答

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。