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