NET簡談組件程序設(shè)計(jì)之(AppDomain應(yīng)用程序域)
.NET 簡談組件程序設(shè)計(jì)之(AppDomain應(yīng)用程序域) 最近在苦學(xué).NET底層框架模型,發(fā)現(xiàn).NET深入真的不是一般的難,不開源、沒有相關(guān)系統(tǒng)的官方的書籍做學(xué)習(xí)資料,只能零散的看MSDN。要想摸
.NET 簡談組件程序設(shè)計(jì)之(AppDomain應(yīng)用程序域) 最近在苦學(xué).NET底層框架模型,發(fā)現(xiàn).NET深入真的不是一般的難,不開源、沒有相關(guān)系統(tǒng)的官方的書籍做學(xué)習(xí)資料,只能零散的看MSDN。要想摸熟.NET的模型真的并非易事。慢慢來吧。[王清培版權(quán)所有,轉(zhuǎn)載請給出署名]
.NET 應(yīng)用程序域(AppDomain)是我們所有.NET應(yīng)用程序的邏輯宿主容器。初次接觸會感覺到AppDomain 離我們?nèi)粘i_發(fā)比較遠(yuǎn),不常用到。其實(shí)是我們很少接觸一些復(fù)雜而底層的系統(tǒng)結(jié)構(gòu)。在日常的開發(fā)中,我們多數(shù)是基于數(shù)據(jù)庫的管理信息系統(tǒng)(MIS),做增、刪、改、查的操作。我始終認(rèn)為作為開發(fā)人員要注意自己的發(fā)展方向,要時刻提醒自己的職業(yè)規(guī)劃,不要盲目的將自己的黃金時間用在“尋找另一艘行駛很慢的小帆船上”【.NET之降龍十八掌】,在我們打算將整個人生都投入到IT 中時,視乎有很多時間可以利用,但是仔細(xì)想想我們能用的時間很少。一天下來除去工作的時間就是休息的時間,我們只能剝削自己休息的時間,更是剝奪陪家人的時間。就想周公【周公的專欄】所說的,我們的生活不僅僅只有技術(shù),我們應(yīng)該只剝奪自己的時間而不是剝奪陪家人的時間。在家人休息的時候我們用來學(xué)習(xí),在家人出去買菜的時候我們用來學(xué)習(xí),在家人需要你的時候千萬不要用“我要學(xué)習(xí)”的借口回避。
[王清培版權(quán)所有,轉(zhuǎn)載請給出署名]
言歸正傳,上面只是本人對生活的一點(diǎn)小小的感悟吧。
本篇文章我們來簡單的了解一下.NET邏輯宿主的相關(guān)概念。
在傳統(tǒng)的Win32的程序中,進(jìn)程是獨(dú)立的運(yùn)行空間,在一些大型系統(tǒng)中,通常都是將系統(tǒng)中的核心功能分解出來用獨(dú)立的進(jìn)程來處理,一方面是為了能獲得更高的系統(tǒng)性能、吞吐量。另一方面是為了能隔離功能之間的錯誤異常,為了使功能之間互不干擾,用進(jìn)程進(jìn)行隔離,再通過IPC 或者其他的方式進(jìn)行進(jìn)程間通信,當(dāng)某個功能發(fā)生嚴(yán)重錯誤的時候不會使整個系統(tǒng)強(qiáng)制關(guān)閉。
其實(shí).NET的應(yīng)用程序域誕生的初衷有點(diǎn)這個意思,用AppDomain 進(jìn)行隔離錯誤異常。在我們開發(fā)大型系統(tǒng)的時候,或者是開發(fā)系統(tǒng)核心組件的時候肯定是需要考慮系統(tǒng)的容錯性的,尤其是在一些實(shí)時監(jiān)控的功能,是絕對不允許出現(xiàn)異常中斷整個系統(tǒng)的。
那么.NET為我們提供了AppDomain 的概念,它是程序在進(jìn)程中的邏輯宿主。既然是邏輯宿主,那么他們還是共享同一地址空間。在系統(tǒng)的托管堆中還是不分AppDomain 的概念的。[王清培版權(quán)所有,轉(zhuǎn)載請給出署名]
每一個可執(zhí)行應(yīng)用程序都會獨(dú)立開啟一個進(jìn)程,當(dāng)系統(tǒng)加載器將控制權(quán)交給CLR 的時候,.NET會用默認(rèn)的AppDomain 來宿主應(yīng)用程序。默認(rèn)的應(yīng)用程序域是由.NET開啟的,當(dāng)系統(tǒng)啟動起來之后,我們可以創(chuàng)建應(yīng)用程序域,然后在該域里面創(chuàng)建對象。【其實(shí)我真的很想知道到底AppDomain 是怎么起到隔離的作用的,如果哪位高手了解的請賜教?!?/p> ,
我們看一個下例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
1516
17
18
19
20
21}}}namespace MyClassLibrary {///
我定義一個Class2的類,繼承自MarshalByRefObject 對象,該對象是跨域遠(yuǎn)程訪問的抽象基類,使用引用傳遞進(jìn)行調(diào)用。后面講到遠(yuǎn)程處理的時候我們再來詳細(xì)的分解MarshalByRefObject 對象。
22//創(chuàng)建新的應(yīng)用程序域
23Console.WriteLine("default
AppDomain.CurrentDomain.FriendlyName);
24AppDomain newdomain =AppDomain.CreateDomain("newadddomain");
25
26object refobject =newdomain.CreateInstanceAndUnwrap("MyClassLibrary","MyClassLibrary.Class2");
27(refobjectas MyClassLibrary.Class2).PrintAppDomain();
28Console.Read();appdomain name:n"
我們首先輸出默認(rèn)的應(yīng)用程序域的名稱,通常是應(yīng)用程序的名稱。如果在VS 調(diào)試環(huán)境下會出現(xiàn)AppName.VsHost.exe 名稱。這是因?yàn)閂S 為了調(diào)試用自己的進(jìn)程來啟動我們的程序。然后在默認(rèn)的應(yīng)用程序域的里面創(chuàng)建了一個新的應(yīng)用程序域,域名為newadddomain,其實(shí)這個時候我們拿到僅僅是新應(yīng)用程序的透明代理。
,
這個客戶端透明代理對象,背后隱藏了一個真實(shí)代理。細(xì)節(jié)我們后面文章在討論。細(xì)節(jié)這里就不扯了。
我們來看一下應(yīng)用程序域是大概怎么創(chuàng)建的,包括代理的創(chuàng)建、位置的保存。
簡單解釋一下:客戶端通過AppDomain 靜態(tài)方法創(chuàng)建一個新的應(yīng)用程序域,然后封裝ObjRef 對象,由于要在客戶端應(yīng)用程序域中調(diào)用新的應(yīng)用程序的功能,設(shè)計(jì)到了跨域的訪問,所以.NET通過ObjRef 保存新的應(yīng)用程序的位置信息以便在客戶端生成代理。當(dāng)ObjRef 到達(dá)客戶端之后,系統(tǒng)進(jìn)行反序列化進(jìn)行動態(tài)構(gòu)造真實(shí)代理和透明代理,透明代理是動態(tài)創(chuàng)建的,必須繼承自我們客戶端調(diào)用的類型,可能用到了一些動態(tài)生成、編譯的技術(shù)。ObjRef 擴(kuò)展自MarShalByRefObject 對象,專門用來保存服務(wù)端對象的位置信息,并且是可序列化的。本文出自“深度訓(xùn)練(DotNet專場) ”博客,請務(wù)必保留此出處http://wangqingpei557.blog.51cto.com/1009349/665249