2009-08-10 59 views
13

我必須調用一些編寫得很差的第三方COM組件,這些組件有內存泄漏,並在長時間運行的過程中使用單線程公寓[STA]。AppDomain是否等價於.NET代碼的進程?

我知道單獨的過程將是實現它的好方法,我可以偶爾從長時間運行的過程中重新啓動它。

是否可以使用AppDomain? AppDomain是否線程一個STA線程如果適當標記?它有它自己的COM對象的內存嗎?卸載AppDomain是否等同於殺死進程?

回答

22

一個AppDomain不提供相同作爲一個過程的孤立程度。事實上,如果您擔心第三方組件狀況不佳,那麼存在風險,它會取消您的.NET應用程序。

如果在卸載時執行非託管代碼,則無法卸載AppDomain,因此您可能很難控制AppDomain中的第三方代碼。請參閱http://msdn.microsoft.com/en-us/library/system.appdomain.unload.aspx

即使僅用於託管代碼,AppDomain也不提供強大的沙盒解決方案。例如。如果加載的代碼產生任何線程,則在未處理的異常情況下這些線程將取消整個進程。這個問題有更多的信息:.NET - What's the best way to implement a "catch all exceptions handler"

據我所知,在.NET應用程序中託管代碼的最佳選擇是實現您自己的CLR主機進程,如IIS和SQL Server。

+0

+1。比我的嘗試要好得多。 :) – 2009-08-10 05:49:48

0

AppDomain(應用程序域)是應用程序執行的獨立環境。

它們幫助提供隔離, 卸載以及執行託管代碼的 的安全邊界。

  • 使用應用程序域隔離可能導致進程的任務。 如果執行任務的AppDomain的狀態變得不穩定,則可以在不影響進程的情況下卸載AppDomain,而不會影響 。當進程必須長時間運行 而不重新啓動時,這是重要的 。您還可以使用應用程序域 隔離不應共享 數據的任務。

  • 如果程序集加載到默認應用程序域中,則在運行 進程時,不能從內存中卸載 。但是,如果您 打開第二個應用程序域到 加載並執行程序集,卸載 應用程序域時會卸載程序集 。使用 這種技術可以最大限度地減少 偶爾使用大型DLL的長時間運行的進程集。

多個應用程序域可以在單個進程中運行 ;但是, 不是 應用程序域和線程之間的一對一關聯。 幾個線程可以屬於單個應用程序域,並且給定的 線程不限於單個應用程序域,在任何給定時間,線程都在單個應用程序域中執行。

SO問題可能會感興趣:

我不會自稱是在應用程序域的領域的專家,但我相當確信,泄漏內存的COM對象(即非託管內存)將不會被你釋放加載AppDomain。也許更熟悉這個的人可以發表評論。

正如布賴恩指出,「......在.NET Framework 2.0版域不保證卸載,因爲它可能無法終止正在執行的線程。」

+2

那麼你爲Rohit推薦什麼樣的行動? – 2009-08-10 05:35:48

+0

@ spoon16:歡迎您添加自己的答案。 ;) – 2009-08-10 05:38:48

+0

我很好奇,看看答案是什麼。我現在沒有一個提供。 – 2009-08-10 05:39:36