天天看點

.NET簡談元件程式設計之(AppDomain應用程式域)

最近在苦學.NET底層架構模型,發現.NET深入真的不是一般的難,不開源、沒有相關系統的官方的書籍做學習資料,隻能零散的看MSDN。要想摸熟.NET的模型真的并非易事。慢慢來吧。[王清培版權所有,轉載請給出署名]

言歸正傳,上面隻是本人對生活的一點小小的感悟吧。

本篇文章我們來簡單的了解一下.NET邏輯宿主的相關概念。

在傳統的Win32的程式中,程序是獨立的運作空間,在一些大型系統中,通常都是将系統中的核心功能分解出來用獨立的程序來處理,一方面是為了能獲得更高的系統性能、吞吐量。另一方面是為了能隔離功能之間的錯誤異常,為了使功能之間互不幹擾,用程序進行隔離,再通過IPC或者其他的方式進行程序間通信,當某個功能發生嚴重錯誤的時候不會使整個系統強制關閉。

其實.NET的應用程式域誕生的初衷有點這個意思,用AppDomain進行隔離錯誤異常。

在我們開發大型系統的時候,或者是開發系統核心元件的時候肯定是需要考慮系統的容錯性的,尤其是在一些實時監控的功能,是絕對不允許出現異常中斷整個系統的。

那麼.NET為我們提供了AppDomain的概念,它是程式在程序中的邏輯宿主。既然是邏輯宿主,那麼他們還是共享同一位址空間。在系統的托管堆中還是不分AppDomain的概念的。[王清培版權所有,轉載請給出署名]

每一個可執行應用程式都會獨立開啟一個程序,當系統加載器将控制權交給CLR的時候,.NET會用預設的AppDomain來宿主應用程式。預設的應用程式域是由.NET開啟的,當系統啟動起來之後,我們可以建立應用程式域,然後在該域裡面建立對象。【其實我真的很想知道到底AppDomain是怎麼起到隔離的作用的,如果哪位高手了解的請賜教。】

我們看一個下例子:

我定義一個Class2的類,繼承自MarshalByRefObject對象,該對象是跨域遠端通路的抽象基類,使用引用傳遞進行調用。後面講到遠端處理的時候我們再來詳細的分解MarshalByRefObject對象。

我們首先輸出預設的應用程式域的名稱,通常是應用程式的名稱。如果在VS調試環境下會出現AppName.VsHost.exe名稱。這是因為VS為了調試用自己的程序來啟動我們的程式。然後在預設的應用程式域的裡面建立了一個新的應用程式域,域名為newadddomain,其實這個時候我們拿到僅僅是新應用程式的透明代理。

.NET簡談元件程式設計之(AppDomain應用程式域)

這個用戶端透明代理對象,背後隐藏了一個真實代理。細節我們後面文章在讨論。

.NET簡談元件程式設計之(AppDomain應用程式域)

細節這裡就不扯了。

我們來看一下應用程式域是大概怎麼建立的,包括代理的建立、位置的儲存。

.NET簡談元件程式設計之(AppDomain應用程式域)

用程式域中調用新的應用程式的功能,設計到了跨域的通路,是以.NET通過ObjRef儲存新的應用程式的位置資訊以便在用戶端生成代理。當ObjRef到達用戶端之後,系統進行反序列化進行動态構造真實代理和透明代理,透明代理是動态建立的,必須繼承自我們用戶端調用的類型,可能用到了一些動态生成、編譯的技術。ObjRef擴充自MarShalByRefObject對象,專門用來儲存服務端對象的位置資訊,并且是可序列化的。