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





