• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題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關鍵字專題關鍵字專題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
    當前位置: 首頁 - 科技 - 知識百科 - 正文

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

    來源:懂視網 責編:小采 時間:2020-11-27 22:37:07
    文檔

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

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

    一、遠程對象的激活

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

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

    二、生命周期

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

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

    1、租用

      租用是個封裝了TimeSpan值的對象,用以管理遠程對象的生存期。在.Net Remoting中提供了定義租用功能的ILease接口。當Remoting通過SingleTon模式或客戶端激活模式來激活遠程對象時,租用對象調用從System.MarshalByRefObject繼承的InitializeLifetimeService方法,向對象請求租用。

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

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

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

    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; 
    }

    也可以忽略該方法,將對象的租用周期改變為無限:

    public override object InitializeLifetimeService()
    {
     return null;
    }

    2、租用管理器

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

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

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

    LifetimeServices.LeaseTime = TimeSpan.Zero;

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

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

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

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

    3、發起人(Sponsor)

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

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

      客戶端要使用發起人機制,必須創建ClientSponsor類的一個實例。然后調用相關方法如Register()或Renewal()方法來注冊遠程對象或延長生命周期。如:

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

    續租時間也可以在ClientSponsor的構造函數中直接設置,如:

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

    我們也可以自己編寫Sponsor來管理發起人機制,這個類必須繼承ClientSponsor并實現ISponsor接口。

    三、跟蹤服務

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

      我們可以創建一個簡單的跟蹤處理程序,該程序實現接口ITrackingHandler。接口ITrackingHandler定義了3個方法,MarshalObject、UnmarshalObject和DisconnectedObject。當遠程對象被編組、解組和斷開連接時,就會調用相應的方法。下面是該跟蹤處理類的代碼:

    public class MyTracking:ITrackingHandler
    {
     public MyTracking()
     {
     //
     // TODO: 在此處添加構造函數邏輯
     //
     }
    
     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());
     }
    }
    
    

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

    四、測試

    1、建立兩個遠程對象,并重寫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、服務器端

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

    (2) 注冊通道:

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

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

    LifetimeServices.LeaseTime = TimeSpan.Zero;

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

    TrackingServices.RegisterTrackingHandler(new MyTracking());

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

    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) 使服務器端保持運行:

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

    3、客戶端

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

    4、運行測試:

    運行服務器端和客戶端,由于監控程序將監視遠程對象的編組進程,因此在運行開始,就會顯示遠程對象已經被Marshal:

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

    然后再客戶端調用這兩個遠程對象的PrintString方法,服務器端接受字符串:

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

    一分鐘后,遠程對象一自動被Disconnect:

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

    此時客戶端如要調用遠程對象一,會拋出RemotingException異常;

    又一分鐘后,遠程對象二被Disconnect了:

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

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

    五、結論

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

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

      

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

    文檔

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

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

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 日产精品99久久久久久| 97精品伊人久久久大香线蕉 | 国产精品成人小电影在线观看| 久久香综合精品久久伊人| 欧美激情精品久久久久久久| 1区1区3区4区产品芒果精品| 国产精品免费观看调教网| 亚洲午夜国产精品无码| 精品亚洲欧美中文字幕在线看 | 国产精品美女网站| 久久精品国产精品国产精品污| 久久国产精品99国产精| 亚洲精品欧美精品日韩精品| 久久精品无码一区二区日韩AV| 91久久精品无码一区二区毛片| 99re热视频这里只精品| 国产最新进精品视频| 亚洲精品无码高潮喷水在线| 欧美成人精品网站播放| 国产亚洲精品a在线观看 | 精品国精品无码自拍自在线| 亚洲国产精品成人久久| 中文字幕精品一区| 一本之道av不卡精品| 亚洲精品无码AV中文字幕电影网站| 免费精品视频在线| 免费精品视频在线| 人妻偷人精品成人AV| 下载天堂国产AV成人无码精品网站| 久久夜色精品国产亚洲av| 久久久久久久久久免免费精品| 久久精品国产99国产精品| 久久国产精品免费一区| 牛牛在线精品观看免费正| 日韩亚洲精品福利 | 好湿好大硬得深一点动态图91精品福利一区二区 | 久久99久久99精品免视看动漫| 日韩人妻无码精品一专区| 嫖妓丰满肥熟妇在线精品| 欧美性videos高清精品| 久久久久女人精品毛片|