JGTM‘2004 [MVP] 對(duì)MarshalByRefObject的講解
問(wèn):
打擾一下,請(qǐng)問(wèn)MarshalByRefObject中的"Marshal"應(yīng)該怎樣理解?
回復(fù):
按照package的意思理解——當(dāng)一個(gè)對(duì)象需要長(zhǎng)途跋涉到另一個(gè)環(huán)境中時(shí),需要將其marshal成一個(gè)可以傳輸?shù)男螒B(tài)(比如在.NET Remoting中對(duì)象將被打包成一個(gè)serializable的ObjRef實(shí)例——這個(gè)ByRef就是指ObjRef這種形態(tài));同理,當(dāng)打包以后傳輸?shù)侥繕?biāo)地點(diǎn),還要執(zhí)行unmarshal的操作將其還原為內(nèi)存中的對(duì)象。:)
問(wèn):
謝謝!
MarshalByRefObject是不是可以這樣理解:對(duì)被引用的對(duì)象進(jìn)行Marshal。如果按照package的意思理解,那package的過(guò)程是怎樣的?
MSDN上這樣講:
MarshalByRefObject 是通過(guò)使用代理交換消息來(lái)跨應(yīng)用程序域邊界進(jìn)行通訊的對(duì)象的基類.
MarshalByRefObject 對(duì)象在本地應(yīng)用程序域的邊界內(nèi)可直接訪問(wèn)。遠(yuǎn)程應(yīng)用程序域中的應(yīng)用程序首次訪問(wèn)MarshalByRefObject 時(shí),會(huì)向該遠(yuǎn)程應(yīng)用程序傳遞代理。對(duì)該代理后面的調(diào)用將封送回駐留在本地應(yīng)用程序域中的對(duì)象。
在Marshal中,上面所說(shuō)的代理是什么?有什么用?
MSDN上還講到:
當(dāng)跨應(yīng)用程序域邊界使用類型時(shí),類型必須是從 MarshalByRefObject 繼承的,而且由于對(duì)象的成員在創(chuàng)建它們的應(yīng)用程序域之外無(wú)法使用,所以不得復(fù)制對(duì)象的狀態(tài)。
既然對(duì)象的狀態(tài)不能傳遞過(guò)去,那傳遞這個(gè)對(duì)象又有何意義?
第一次去理解MarshalByRefObject,有的問(wèn)題可能提的比較膚淺,請(qǐng)您指點(diǎn)。
回復(fù):
MarshalByRefObject是所有可以在AppDomain邊界外部訪問(wèn)的對(duì)象的基類,重心不是marshal,而是object,即object that could be marshaled by reference,也就是可以通過(guò)Ref(實(shí)際上是ObjRef對(duì)象)的機(jī)制進(jìn)行“封送”(MSDN中文版對(duì)marshal一詞的翻譯)的對(duì)象。封送的行為是由代理來(lái)做的,這里說(shuō)的代理就是我文章中講過(guò)的.NET Remoting的真實(shí)代理(即RemotingProxy)。真實(shí)代理不是有一個(gè)Invoke()方法嗎?當(dāng)你透過(guò)對(duì)一個(gè)MBRO的透明代理訪問(wèn)該對(duì)象的方法時(shí),透明代理將把基于堆棧的方法調(diào)用轉(zhuǎn)換為方法調(diào)用消息(IMethodCallMessage)并轉(zhuǎn)發(fā)給真實(shí)代理(在Remoting的場(chǎng)合中也即RemotingProxy),而RemotingProxy的任務(wù)就是把對(duì)象封送并連同方法調(diào)用消息一起轉(zhuǎn)發(fā)給遠(yuǎn)程應(yīng)用程序域;到達(dá)目的地以后的操作類似:遠(yuǎn)程應(yīng)用程序域中的監(jiān)聽(tīng)方當(dāng)收到發(fā)來(lái)的方法調(diào)用消息時(shí),先取出封送好的ObjRef(這個(gè)對(duì)象里面保存著發(fā)來(lái)調(diào)用的那個(gè)對(duì)象?。?,將其結(jié)封(unmarshal)為本地的對(duì)象,并獲得其透明代理,然后就可以把方法調(diào)用消息在轉(zhuǎn)換回基于堆棧的調(diào)用發(fā)送給這個(gè)對(duì)象。
對(duì)象是在本地維護(hù)的,但是方法可以在遠(yuǎn)程調(diào)用。你比如說(shuō)一個(gè)web應(yīng)用程序,你是通過(guò)本地的瀏覽器遠(yuǎn)程訪問(wèn)這個(gè)應(yīng)用程序,但是應(yīng)用程序的狀態(tài)不會(huì)由你的瀏覽器負(fù)責(zé)(所以你只是在訪問(wèn)這個(gè)應(yīng)用程序提供給你的功能而已,你并沒(méi)于擁有應(yīng)用程序本身,包括其所有數(shù)據(jù)),你只是發(fā)送一個(gè)個(gè)的請(qǐng)求,服務(wù)器告訴你處理的結(jié)果。在Remoting中也是一樣,當(dāng)你獲得一個(gè)遠(yuǎn)程對(duì)象的時(shí)候,你實(shí)際上只擁有對(duì)這個(gè)對(duì)象的一個(gè)遠(yuǎn)程引用,雖然你可以調(diào)用它的方法,但實(shí)際上這些操作都是發(fā)生在遠(yuǎn)程的(就是前面講過(guò)的過(guò)程),你只是傳入了一些參數(shù),得到了一個(gè)結(jié)果,但對(duì)象的狀態(tài)還是在遠(yuǎn)程維護(hù)的(換句話說(shuō),對(duì)象本身也就是對(duì)象的所有狀態(tài)并沒(méi)有被往返傳遞,傳遞的只是傳入傳出的參數(shù)——當(dāng)然,如果參數(shù)是一個(gè)MBRO的話,還是傳遞對(duì)象被封送的引用)。
也許應(yīng)該給你準(zhǔn)備一個(gè)好理解的例子……你就會(huì)豁然開朗了。:)
問(wèn):
我這樣的理解對(duì)不對(duì)?
一般的對(duì)象與從MarshalByRefObject繼承的對(duì)象區(qū)別是:
一般的對(duì)象只能在本地應(yīng)用程序域之內(nèi)被引用,而MarshalByRefObject對(duì)象可以跨越應(yīng)用程序域邊界被引用,甚至被遠(yuǎn)程引用。
回復(fù):
Exactly! 當(dāng)對(duì)象跨出AppDomain邊界的時(shí)候,實(shí)際上只是它的一個(gè)引用(ObjRef)。你比如說(shuō)吧:
public class LocalObject
{
public void CallRemoteObject(MarshalByRefObject mbro)
{
Console.WriteLine(mbro.ToString());
}
}
posted on 2004-03-04 22:29 dudu 閱讀(791) 評(píng)論(0) 編輯 收藏 收藏至365Key