<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        Microsoft .Net Remoting系列教程之二:Marshal、Disconnect與生命周期以及跟蹤服務(wù)

        來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 22:37:07
        文檔

        Microsoft .Net Remoting系列教程之二:Marshal、Disconnect與生命周期以及跟蹤服務(wù)

        Microsoft .Net Remoting系列教程之二:Marshal、Disconnect與生命周期以及跟蹤服務(wù):一、遠(yuǎn)程對象的激活 在Remoting中有三種激活方式,一般的實現(xiàn)是通過RemotingServices類的靜態(tài)方法來完成。工作過程事實上是將該遠(yuǎn)程對象注冊到通道中。由于Remoting沒有提供與之對應(yīng)的Unregister方法來注銷遠(yuǎn)程對象,所以如果需要注冊/注銷指定對象,微軟推
        推薦度:
        導(dǎo)讀Microsoft .Net Remoting系列教程之二:Marshal、Disconnect與生命周期以及跟蹤服務(wù):一、遠(yuǎn)程對象的激活 在Remoting中有三種激活方式,一般的實現(xiàn)是通過RemotingServices類的靜態(tài)方法來完成。工作過程事實上是將該遠(yuǎn)程對象注冊到通道中。由于Remoting沒有提供與之對應(yīng)的Unregister方法來注銷遠(yuǎn)程對象,所以如果需要注冊/注銷指定對象,微軟推

        一、遠(yuǎn)程對象的激活

          在Remoting中有三種激活方式,一般的實現(xiàn)是通過RemotingServices類的靜態(tài)方法來完成。工作過程事實上是將該遠(yuǎn)程對象注冊到通道中。由于Remoting沒有提供與之對應(yīng)的Unregister方法來注銷遠(yuǎn)程對象,所以如果需要注冊/注銷指定對象,微軟推薦使用Marshal(一般譯為編組)和Disconnect配對使用。在《Net Remoting基礎(chǔ)篇》中我已經(jīng)談到:Marshal()方法是將MarshalByRefObject類對象轉(zhuǎn)化為ObjRef類對象,這個對象是存儲生成代理以與遠(yuǎn)程對象通訊所需的所有相關(guān)信息。這樣就可以將該實例序列化以便在應(yīng)用程序域之間以及通過網(wǎng)絡(luò)進(jìn)行傳輸,客戶端就可以調(diào)用了。而Disconnect()方法則將具體的實例對象從通道中斷開。

          根據(jù)上述說明,Marshal()方法對遠(yuǎn)程對象以引用方式進(jìn)行編組(Marshal-by-Reference,MBR),并將對象的代理信息放到通道中。客戶端可以通過Activator.GetObject()來獲取。如果用戶要注銷該對象,則通過調(diào)用Disconnect()方法。那么這種方式對于編組的遠(yuǎn)程對象是否存在生命周期的管理呢?這就是本文所要描述的問題。

        二、生命周期

          在CLR中,框架提供了GC(垃圾回收器)來管理內(nèi)存中對象的生命周期。同樣的,.Net Remoting使用了一種分布式垃圾回收,基于租用的形式來管理遠(yuǎn)程對象的生命周期。

          早期的DCOM對于對象生命周期的管理是通過ping和引用計數(shù)來確定對象何時應(yīng)當(dāng)作為垃圾回收。然而ping引起的網(wǎng)絡(luò)流量對分布式應(yīng)用程序的性能是一種痛苦的負(fù)擔(dān),它大大地影響了分布式處理的整體性能。.Net Remoting在每個應(yīng)用程序域中都引入一個租用管理器,為每個服務(wù)器端的SingleTon,或每個客戶端激活的遠(yuǎn)程對象保存著對租用對象的引用。(說明:對于服務(wù)器端激活的SingleCall方式,由于它是無狀態(tài)的,對于每個激活的遠(yuǎn)程對象,都由CLR的GC來自動回收,因此對于SingleCall模式激活的遠(yuǎn)程對象,不存在生命周期的管理。)

        1、租用

          租用是個封裝了TimeSpan值的對象,用以管理遠(yuǎn)程對象的生存期。在.Net Remoting中提供了定義租用功能的ILease接口。當(dāng)Remoting通過SingleTon模式或客戶端激活模式來激活遠(yuǎn)程對象時,租用對象調(diào)用從System.MarshalByRefObject繼承的InitializeLifetimeService方法,向?qū)ο笳埱笞庥谩?/p>

        ILease接口定義了有關(guān)生命周期的屬性,均為TimeSpan值。如下:

        InitialLeaseTime:初始化有效時間,默認(rèn)值為300秒,如果為0,表示永不過期;
        RenewOnCallTime:調(diào)用遠(yuǎn)程對象一個方法時的租用更新時間,默認(rèn)值為120秒;
        SponsorshipTimeout:超時值,通知Sponsor(發(fā)起人)租用過期后,Remoting會等待的時間,默認(rèn)值為120秒;
        CurrentLeaseTime:當(dāng)前租用時間,首次獲得租用時,為InitializeLeaseTime的值。

        Remoting的遠(yuǎn)程對象因為繼承了MarshalByRefObject,因此默認(rèn)繼承了InitializeLifetimeService方法,那么租用的相關(guān)屬性為默認(rèn)值。如果要改變這些設(shè)置,可以在遠(yuǎn)程對象中重寫該方法。例如:

        public override object InitializeLifetimeService()
        {
         ILease lease = (ILease)base.InitializeLifetimeService();
         if (lease.CurrentState == LeaseState.Initial)
         {
         lease.InitialLeaseTime = TimeSpan.FromMinutes(1);
         lease.RenewOnCallTime = TimeSpan.FromSeconds(20);
         }
         return lease; 
        }

        也可以忽略該方法,將對象的租用周期改變?yōu)闊o限:

        public override object InitializeLifetimeService()
        {
         return null;
        }

        2、租用管理器

          如果是前面所說的租用主要是應(yīng)用在每個具體的遠(yuǎn)程對象上,那么租用管理器是服務(wù)器端專門用來管理遠(yuǎn)程對象生命周期的管理器,它維持著一個System.Hashtable成員,將租用映射為System.DateTime實例表示每個租用何時應(yīng)過期。Remoting采用輪詢的方式以一定的時間喚醒租用管理器,檢查每個租用是否過期。默認(rèn)為每10秒鐘喚醒一次。輪詢的間隔可以配置,如將輪詢間隔設(shè)置為5分鐘:

        LifetimeService.LeaseManagerPollTime = System.TimeSpan.FromMinutes(5);

        我們還可以在租用管理器中設(shè)置遠(yuǎn)程對象租用的屬性,如改變遠(yuǎn)程對象的初始有效時間為永久有效:

        LifetimeServices.LeaseTime = TimeSpan.Zero;

        我們也可以通過配置文件來設(shè)置生命周期,如:

        <configuration>
         <system.runtime.remoting>
         <application name = "SimpleServer">
         <lifetime leaseTime = "0" sponsorshipTimeOut = "1M" renewOnCallTime = "1M" pollTime = "30S"/> 
         </application>
         </system.runtime.remoting>
        </configuration>

        注:配置文件中的pollTime即為上面所說的租用管理器的輪詢間隔時間LeaseManagerPollTime。

          租用管理器對于生命周期的設(shè)置是針對服務(wù)器上所有的遠(yuǎn)程對象。當(dāng)我們通過配置文件或租用管理器設(shè)置租用的屬性時,所有遠(yuǎn)程對象的生命周期都遵循該設(shè)置,除非我們對于指定的遠(yuǎn)程對象通過重寫InitializeLifetimeService方法,改變了相關(guān)配置。也就是說,遠(yuǎn)程對象的租用配置優(yōu)先級高于服務(wù)器端配置。

        3、發(fā)起人(Sponsor)

          發(fā)起人是針對客戶端而言的。遠(yuǎn)程對象就是發(fā)起人要租用的對象,發(fā)起人可以與服務(wù)器端簽訂租約,約定租用時間。一旦到期后,發(fā)起人還可以續(xù)租,就像現(xiàn)實生活中租方的契約,房東、租房者之間的關(guān)系一樣。

          在.Net Framework中的System.Runtime.Remoting.Lifetime命名空間中定義了ClientSponsor類,該類繼承了System.MarshalByRefObject,并實現(xiàn)了ISponsor接口。ClientSponsor類的屬性和方法,可以參考MSDN。

          客戶端要使用發(fā)起人機(jī)制,必須創(chuàng)建ClientSponsor類的一個實例。然后調(diào)用相關(guān)方法如Register()或Renewal()方法來注冊遠(yuǎn)程對象或延長生命周期。如:

        RemotingObject obj = new RemotingObject();
        ClientSponsor sponsor = new ClientSponsor();
        sponsor.RenewalTime = TimeSpan.FromMinutes(2);
        sponsor.Register(obj);

        續(xù)租時間也可以在ClientSponsor的構(gòu)造函數(shù)中直接設(shè)置,如:

        ClientSponsor sponsor = new ClientSponsor(TimeSpan.FromMinutes(2));
        sponsor.Register(obj);

        我們也可以自己編寫Sponsor來管理發(fā)起人機(jī)制,這個類必須繼承ClientSponsor并實現(xiàn)ISponsor接口。

        三、跟蹤服務(wù)

          如前所述,我們要判斷通過Marshal編組遠(yuǎn)程對象是否存在生命周期的管理。在Remoting中,可以通過跟蹤服務(wù)程序來監(jiān)視MBR對象的編組進(jìn)程。

          我們可以創(chuàng)建一個簡單的跟蹤處理程序,該程序?qū)崿F(xiàn)接口ITrackingHandler。接口ITrackingHandler定義了3個方法,MarshalObject、UnmarshalObject和DisconnectedObject。當(dāng)遠(yuǎn)程對象被編組、解組和斷開連接時,就會調(diào)用相應(yīng)的方法。下面是該跟蹤處理類的代碼:

        public class MyTracking:ITrackingHandler
        {
         public MyTracking()
         {
         //
         // TODO: 在此處添加構(gòu)造函數(shù)邏輯
         //
         }
        
         public void MarshaledObject(object obj,ObjRef or)
         {
         Console.WriteLine();
         Console.WriteLine("對象" + obj.Tostring() + " is marshaled at " + DateTime.Now.ToShortTimeString());
         }
        
         public void UnmarshaledObject(object obj,ObjRef or)
         {
         Console.WriteLine();
         Console.WriteLine("對象" + obj.Tostring() + " is unmarshaled at " + DateTime.Now.ToShortTimeString());
         }
        
         public void DisconnectedObject(object obj)
         {
         Console.WriteLine(obj.ToString() + " is disconnected at " + DateTime.Now.ToShortTimeString());
         }
        }
        
        

        然后再服務(wù)器端創(chuàng)建該跟蹤處理類的實例,并注冊跟蹤服務(wù):
        TrackingServices.RegisterTrackingHandler(new MyTracking());

        四、測試

        1、建立兩個遠(yuǎn)程對象,并重寫InitializeLifetimeService方法:

        對象一:AppService1
        初始生命周期:1分鐘

        public class AppService1:MarshalByRefObject
        {
         public void PrintString(string contents)
         {
         Console.WriteLine(contents); 
         }
        
         public override object InitializeLifetimeService()
         {
         ILease lease = (ILease)base.InitializeLifetimeService();
         if (lease.CurrentState == LeaseState.Initial)
         {
         lease.InitialLeaseTime = TimeSpan.FromMinutes(1);
         lease.RenewOnCallTime = TimeSpan.FromSeconds(20);
         }
         return lease;
         }
        }
        
        

        對象二:AppService2
        初始生命周期:3分鐘

        public class AppService2:MarshalByRefObject
        {
         public void PrintString(string contents)
         {
         Console.WriteLine(contents); 
         }
        
         public override object InitializeLifetimeService()
         {
         ILease lease = (ILease)base.InitializeLifetimeService();
         if (lease.CurrentState == LeaseState.Initial)
         {
         lease.InitialLeaseTime = TimeSpan.FromMinutes(3);
         lease.RenewOnCallTime = TimeSpan.FromSeconds(40);
         }
         return lease;
         }
        }
        
        

        為簡便起見,兩個對象的方法都一樣。

        2、服務(wù)器端

        (1) 首先建立如上的監(jiān)控處理類;

        (2) 注冊通道:

        TcpChannel channel = new TcpChannel(8080);
        ChannelServices.RegisterChannel(channel);

        (3) 設(shè)置租用管理器的初始租用時間為無限:

        LifetimeServices.LeaseTime = TimeSpan.Zero;

        (4) 創(chuàng)建該跟蹤處理類的實例,并注冊跟蹤服務(wù):

        TrackingServices.RegisterTrackingHandler(new MyTracking());

        (5) 編組兩個遠(yuǎn)程對象:

        ServerAS.AppService1 service1 = new ServerAS1.AppService1();
        ObjRef objRef1 = RemotingServices.Marshal((MarshalByRefObject)service1,"AppService1");
        
        ServerAS.AppService2 service2 = new ServerAS1.AppService2();
        ObjRef objRef2 = RemotingServices.Marshal((MarshalByRefObject)service2,"AppService2");
        

        (6) 使服務(wù)器端保持運行:

        Console.WriteLine("Remoting服務(wù)啟動,按退出..."); 
        Console.ReadLine();

        3、客戶端

        通過Activator.GetObject()獲得兩個遠(yuǎn)程對象,并調(diào)用其方法PrintString。代碼略。

        4、運行測試:

        運行服務(wù)器端和客戶端,由于監(jiān)控程序?qū)⒈O(jiān)視遠(yuǎn)程對象的編組進(jìn)程,因此在運行開始,就會顯示遠(yuǎn)程對象已經(jīng)被Marshal:

        http://files.jb51.net/file_images/article/201605/201605300945331.gif

        然后再客戶端調(diào)用這兩個遠(yuǎn)程對象的PrintString方法,服務(wù)器端接受字符串:

        http://files.jb51.net/file_images/article/201605/201605300945332.gif

        一分鐘后,遠(yuǎn)程對象一自動被Disconnect:

        http://files.jb51.net/file_images/article/201605/201605300945333.gif

        此時客戶端如要調(diào)用遠(yuǎn)程對象一,會拋出RemotingException異常;

        又一分鐘后,遠(yuǎn)程對象二被Disconnect了:

        http://files.jb51.net/file_images/article/201605/201605300945334.gif

          用戶還可以根據(jù)這個代碼測試RenewOnCallTime的時間是否正確。也即是說,在對象還未被Disconnect時,調(diào)用對象,則從調(diào)用對象的這一刻起,其生命周期不再是原來設(shè)定的初始有效時間值(InitialLeaseTime),而是租用更新時間值(RenewOnCallTime)。另外,如果這兩個遠(yuǎn)程對象沒有重寫InitializeLifetimeService方法,則生命周期應(yīng)為租用管理器所設(shè)定的值,為永久有效(設(shè)置為0)。那么這兩個對象不會被自動Disconnect,除非我們顯式指定關(guān)閉它的連接。當(dāng)然,如果我們顯式關(guān)閉連接,跟蹤程序仍然會監(jiān)視到它的變化,然后顯示出來。

        五、結(jié)論

          通過我們的測試,其實結(jié)論已經(jīng)很明顯了。通過Marshal編組的對象要受到租用的生命周期所控制。注意對象被Disconnect,并不是指這個對象被GC回收,而是指這個對象保存在通道的相關(guān)代理信息被斷開了,而對象本身仍然在服務(wù)器端存在。

          所以我們通過Remoting提供服務(wù),應(yīng)根據(jù)實際情況指定遠(yuǎn)程對象的生命周期,如果不指定,則為Remoting默認(rèn)的設(shè)定。要讓所有的遠(yuǎn)程對象永久有效,可以通過配置文件或租用管理器將初始有效時間設(shè)為0。

          

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Microsoft .Net Remoting系列教程之二:Marshal、Disconnect與生命周期以及跟蹤服務(wù)

        Microsoft .Net Remoting系列教程之二:Marshal、Disconnect與生命周期以及跟蹤服務(wù):一、遠(yuǎn)程對象的激活 在Remoting中有三種激活方式,一般的實現(xiàn)是通過RemotingServices類的靜態(tài)方法來完成。工作過程事實上是將該遠(yuǎn)程對象注冊到通道中。由于Remoting沒有提供與之對應(yīng)的Unregister方法來注銷遠(yuǎn)程對象,所以如果需要注冊/注銷指定對象,微軟推
        推薦度:
        標(biāo)簽: 微軟 跟蹤 microsoft
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 久久国产乱子精品免费女| 亚洲欧美日本韩国| g0g0人体全免费高清大胆视频| 永久黄网站色视频免费| 亚洲精品乱码久久久久蜜桃| 德国女人一级毛片免费| 亚洲hairy多毛pics大全| 岛国片在线免费观看| 亚洲av午夜电影在线观看| 国产网站在线免费观看| 猫咪www免费人成网站| 亚洲综合精品网站在线观看| www.xxxx.com日本免费| 亚洲国产精品无码久久久蜜芽| 久久99免费视频| 亚洲喷奶水中文字幕电影 | 亚洲综合精品香蕉久久网97| 日韩精品极品视频在线观看免费 | 女人张开腿等男人桶免费视频| 亚洲色偷偷综合亚洲av78| 国产不卡免费视频| 国产高潮流白浆喷水免费A片 | 亚洲av伊人久久综合密臀性色| 精品无码国产污污污免费网站| 亚洲小视频在线播放| 日韩精品无码人妻免费视频| 无遮挡国产高潮视频免费观看| 亚洲最大AV网站在线观看| 98精品全国免费观看视频| 四虎必出精品亚洲高清| 亚洲精品偷拍视频免费观看| 色猫咪免费人成网站在线观看| 中文字幕 亚洲 有码 在线 | 久久免费观看视频| 亚洲视频手机在线| 国产免费变态视频网址网站| a级毛片免费高清毛片视频| 亚洲色大成网站www永久网站| 日韩亚洲变态另类中文| 日韩免费精品视频| 久久WWW免费人成—看片|