2010-02-19 66 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。