.Net組件程序設(shè)計(jì)之遠(yuǎn)程調(diào)用(一)
我們知道我們寫的C#代碼是在操作系統(tǒng)邏輯體系結(jié)構(gòu)中最上層的,然而操作系統(tǒng)本身是不會(huì)認(rèn)識(shí)C#代碼的,它只認(rèn)識(shí)機(jī)器代碼。那我們寫的程序經(jīng)過編譯后是編譯成IL的,是怎么運(yùn)行的呢?實(shí)際是在一個(gè)托管的環(huán)境下運(yùn)行的,是.NET提供的支持,操作系統(tǒng)是不會(huì)識(shí)別IL的,這中間就需要一個(gè)橋梁:應(yīng)用程序域。操作系統(tǒng)中的進(jìn)程是資源單位,應(yīng)用程序域的執(zhí)行使用當(dāng)然也要占用空間使用資源了,所以是物理進(jìn)程承載著應(yīng)用程序域的,而且這種承載關(guān)系并不是一對(duì)一的。
圖:應(yīng)用程序域
使用應(yīng)用程序域這樣的機(jī)制,是有許多好處的。比如說客戶端在調(diào)用其他組件的時(shí)候可以創(chuàng)建一個(gè)應(yīng)用程序域,然后在新建的應(yīng)用程序域中加載組件進(jìn)行操作等等,即使被調(diào)用的組件發(fā)生一些致命的錯(cuò)誤也不會(huì)導(dǎo)致客戶端崩潰,有效的進(jìn)行了錯(cuò)誤隔離。還有一些數(shù)據(jù)交互傳輸上的性能差異等等,這里不做詳細(xì)的闡述了。
.NET Remoting是一種基于.NET平臺(tái)的分布式系統(tǒng)框架,所了解的就是用于數(shù)據(jù)傳輸。 說幾句它被使用的局限性很大,受到了平臺(tái)的限制,當(dāng)然如果僅僅是這樣是不能否定它的強(qiáng)大和幾乎無限擴(kuò)展的框架體系,無論在哪一個(gè)環(huán)節(jié)你都可以自己來實(shí)現(xiàn)一些自定義的功能。會(huì)在下個(gè)篇幅稍作講解。
在.NET中用AppDoMain類來表示應(yīng)用程序域,也提供了獲取當(dāng)前應(yīng)用程序域的方法,可以直接使用AppDoMain類的靜態(tài)屬性CurrentDomain來獲取到當(dāng)前程序所在的應(yīng)用程序域,這是一種方法,還額外提供一種了,就是Thread類的GetDomain()靜態(tài)方法也是可以獲取到的。
1 namespace RemoteServer 2 public class class1 3 { 4 private string appDoMainName; 5 6 public class1() 7 { 8 appDoMainName = AppDomain.CurrentDomain.FriendlyName; 9 } 10 11 public void Writer() 12 { 13 Console.WriteLine(appDoMainName); 14 } 15 }
class1中構(gòu)造函數(shù)是獲取當(dāng)前應(yīng)用程序域的名稱,并且是在Writer()方法中輸出到控制臺(tái)界面中,
using RemoteServer; namespace RemoteCase { AppDomain appDoMain = AppDomain.CurrentDomain; class1 cls1 = (class1)appDoMain.CreateInstanceFromAndUnwrap("RemoteServer.dll", "RemoteServer.class1"); cls1.Writer(); }
圖3-1
這里使用了AppDomain中的靜態(tài)方法CreateInstanceFromAndUnwrap(),因?yàn)楫?dāng)前項(xiàng)目已經(jīng)引用了RemoteServer程序集,所以第一個(gè)參數(shù)只是一個(gè)顯示的名稱,并不是全路徑,在調(diào)用方法的時(shí)候,應(yīng)用程序域會(huì)加載程序集,用于獲取到元數(shù)據(jù)。
1 namespace RemoteServer 2 public class class1:MarshalByRefObject 3 { 4 private string appDoMainName; 5 6 public class1() 7 { 8 appDoMainName = AppDomain.CurrentDomain.FriendlyName; 9 } 10 11 public void Writer() 12 { 13 Console.WriteLine(appDoMainName); 14 } 15 }
1 using RemoteServer; 2 3 AppDomain appDoMain = AppDomain.CurrentDomain; 4 AppDomain newDoMain = AppDomain.CreateDomain("NewDoMain"); 5 class1 cls1 = (class1)newDoMain.CreateInstanceFromAndUnwrap("RemoteServer.dll", "RemoteServer.class1"); 6 cls1.Writer();
圖3-2
圖3-3-1
這段代碼是3.2中的代碼,cls1并不是class1類型本身,而是代理,訪問遠(yuǎn)程對(duì)象都是通過代理完成的,這么屌炸天的.NET當(dāng)然提供優(yōu)化,將創(chuàng)建遠(yuǎn)程對(duì)象和在客戶端建立代理分離,這樣可以在你創(chuàng)建了一個(gè)遠(yuǎn)程對(duì)象之后再建立代理。 AppDomain類提供了一套CreateInstance()方法來創(chuàng)建對(duì)象,但是都以O(shè)bjectHandle的形式返回一個(gè)遠(yuǎn)程對(duì)象句柄(意思就是遠(yuǎn)程對(duì)象的唯一標(biāo)示,這個(gè)句柄能代表遠(yuǎn)程對(duì)象)
ObjectHandle對(duì)象實(shí)現(xiàn)了System.Runtime.Remoting命名空間下的IObjectHandle接口:
1 namespace RemoteServer 2 public class class1:MarshalByRefObject 3 { 4 private string appDoMainName; 5 6 public class1() 7 { 8 appDoMainName = AppDomain.CurrentDomain.FriendlyName; 9 } 10 11 public void Writer() 12 { 13 Console.WriteLine(appDoMainName); 14 } 15 16 }
1 using RemoteServer; 2 3 AppDomain appDoMain = AppDomain.CurrentDomain; 4 AppDomain newDoMain = AppDomain.CreateDomain("NewDoMain"); 5 IObjectHandle objecthandle; 6 objecthandle = newDoMain.CreateInstance("RemoteServer", "RemoteServer.class1"); 7 8 RemoteServer.class1 cls1 = objecthandle.Unwrap() as RemoteServer.class1; 9 10 cls1.Writer();
一般情況下是不需要手動(dòng)拆包對(duì)象句柄的,這樣做的好處只是可以推遲加載RemoteServer程序集,只有在 objecthandle.Unwrap()的時(shí)候才會(huì)建立代理,而建立代理必須需要對(duì)象元數(shù)據(jù)。
一般情況下,被引用對(duì)象和客戶端同在一個(gè)應(yīng)用程序域,這樣的情況下不涉及到代理,也不會(huì)用到什么遠(yuǎn)程調(diào)用,
而是直接引用對(duì)象,如果當(dāng)你需要調(diào)用另一個(gè)應(yīng)用程序域里的對(duì)象時(shí)會(huì)是什么樣的?默認(rèn)情況下.NET是不允許對(duì)象跨應(yīng)用程序域訪問的,
不管是不是在同一個(gè)進(jìn)程內(nèi)。但是呢如果要訪問,也不是不行的,.NET提供了兩種數(shù)據(jù)傳遞方式,一種是值傳遞,一種是引用傳遞
當(dāng)應(yīng)用程序域A調(diào)用應(yīng)用程序域B中的對(duì)象時(shí),應(yīng)用程序域B中的對(duì)象會(huì)被拷貝一個(gè)克隆到應(yīng)用程序域A,這時(shí)候兩個(gè)對(duì)象是不存在任何關(guān)系的,這種情況叫做按值封送 一般情況下都是使類型使用Serializable特性,支持序列化,通過序列化來達(dá)到按值封送的目的,在被調(diào)用方序列化,到調(diào)用方反序列化。
這種情況就是當(dāng)應(yīng)用程序域A調(diào)用應(yīng)用程序域B的對(duì)象時(shí),應(yīng)用程序域A獲得的是應(yīng)用程序域B中對(duì)象的引用,
這個(gè)引用掛在哪里呢?掛在應(yīng)用程序域A的對(duì)象代理上,這種情況就叫引用封送 引用封送就比按值封送有意思多了,想要滿足可以引用封送的要求,則對(duì)象必須繼承自MarshalByRefObject,MarshalByRefObject類型給出的解釋就是 允許在支持遠(yuǎn)程處理的應(yīng)用程序中跨應(yīng)用程序域邊界訪問對(duì)象,這樣作為它的子類同樣的也享受這樣的優(yōu)待。在引用封送中會(huì)有兩種遠(yuǎn)程對(duì)象激活模式,這個(gè)內(nèi)容在下一個(gè)篇幅中會(huì)有詳細(xì)的示例代碼。
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。
本文題目:.Net組件程序設(shè)計(jì)之遠(yuǎn)程調(diào)用(一)-創(chuàng)新互聯(lián)
鏈接地址:http://jinyejixie.com/article48/dhophp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、App開發(fā)、網(wǎng)站策劃、微信公眾號(hào)、網(wǎng)站內(nèi)鏈、域名注冊(cè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容