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

