欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Microsoft .Net Remoting系列專(zhuān)題之二:Marshal、Disconn...

Microsoft .Net Remoting系列專(zhuān)題之二:Marshal、Disconnect與生命周期以及跟蹤服務(wù)

我寫(xiě)的.Net Remoting系列專(zhuān)題:

Microsoft .Net Remoting系列專(zhuān)題之一:.Net Remoting基礎篇

Microsoft .Net Remoting系列專(zhuān)題之三:Remoting事件處理全接觸

Microsoft .Net Remoting系列專(zhuān)題之二 

一、遠程對象的激活

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

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

二、生命周期

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

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

1、租用

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

ILease接口定義了有關(guān)生命周期的屬性,均為T(mén)imeSpan值。如下:
InitialLeaseTime:初始化有效時(shí)間,默認值為300秒,如果為0,表示永不過(guò)期;
RenewOnCallTime:調用遠程對象一個(gè)方法時(shí)的租用更新時(shí)間,默認值為120秒;
SponsorshipTimeout:超時(shí)值,通知Sponsor(發(fā)起人)租用過(guò)期后,Remoting會(huì )等待的時(shí)間,默認值為120秒;
CurrentLeaseTime:當前租用時(shí)間,首次獲得租用時(shí),為InitializeLeaseTime的值。

Remoting的遠程對象因為繼承了MarshalByRefObject,因此默認繼承了InitializeLifetimeService方法,那么租用的相關(guān)屬性為默認值。如果要改變這些設置,可以在遠程對象中重寫(xiě)該方法。例如:
 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(wú)限:
 public override object InitializeLifetimeService()
 {
  return null;
 }

2、租用管理器

如果是前面所說(shuō)的租用主要是應用在每個(gè)具體的遠程對象上,那么租用管理器是服務(wù)器端專(zhuān)門(mén)用來(lái)管理遠程對象生命周期的管理器,它維持著(zhù)一個(gè)System.Hashtable成員,將租用映射為System.DateTime實(shí)例表示每個(gè)租用何時(shí)應過(guò)期。Remoting采用輪詢(xún)的方式以一定的時(shí)間喚醒租用管理器,檢查每個(gè)租用是否過(guò)期。默認為每10秒鐘喚醒一次。輪詢(xún)的間隔可以配置,如將輪詢(xún)間隔設置為5分鐘:LifetimeService.LeaseManagerPollTime = System.TimeSpan.FromMinutes(5);

我們還可以在租用管理器中設置遠程對象租用的屬性,如改變遠程對象的初始有效時(shí)間為永久有效:
LifetimeServices.LeaseTime = TimeSpan.Zero;

我們也可以通過(guò)配置文件來(lái)設置生命周期,如:
<configuration>
 <system.runtime.remoting>
  <application name = "SimpleServer">
   <lifetime leaseTime = "0" sponsorshipTimeOut = "1M" renewOnCallTime = "1M" pollTime = "30S"/>       
  </application>
 </system.runtime.remoting>
</configuration>

注:配置文件中的pollTime即為上面所說(shuō)的租用管理器的輪詢(xún)間隔時(shí)間LeaseManagerPollTime。

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

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

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

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

客戶(hù)端要使用發(fā)起人機制,必須創(chuàng )建ClientSponsor類(lèi)的一個(gè)實(shí)例。然后調用相關(guān)方法如Register()或Renewal()方法來(lái)注冊遠程對象或延長(cháng)生命周期。如:
RemotingObject obj = new RemotingObject();
ClientSponsor sponsor = new ClientSponsor();
sponsor.RenewalTime = TimeSpan.FromMinutes(2);
sponsor.Register(obj);

續租時(shí)間也可以在ClientSponsor的構造函數中直接設置,如:
ClientSponsor sponsor = new ClientSponsor(TimeSpan.FromMinutes(2));
sponsor.Register(obj);

我們也可以自己編寫(xiě)Sponsor來(lái)管理發(fā)起人機制,這個(gè)類(lèi)必須繼承ClientSponsor并實(shí)現ISponsor接口。

三、跟蹤服務(wù)

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

我們可以創(chuàng )建一個(gè)簡(jiǎn)單的跟蹤處理程序,該程序實(shí)現接口ITrackingHandler。接口ITrackingHandler定義了3個(gè)方法,MarshalObject、UnmarshalObject和DisconnectedObject。當遠程對象被編組、解組和斷開(kāi)連接時(shí),就會(huì )調用相應的方法。下面是該跟蹤處理類(lèi)的代碼: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());
 }
}

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

四、測試

1、建立兩個(gè)遠程對象,并重寫(xiě)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;
   
  }
 }

為簡(jiǎn)便起見(jiàn),兩個(gè)對象的方法都一樣。

2、服務(wù)器端

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

(2) 注冊通道:
TcpChannel channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel);

(3) 設置租用管理器的初始租用時(shí)間為無(wú)限:
LifetimeServices.LeaseTime = TimeSpan.Zero;

(4) 創(chuàng )建該跟蹤處理類(lèi)的實(shí)例,并注冊跟蹤服務(wù):
TrackingServices.RegisterTrackingHandler(new MyTracking());

(5) 編組兩個(gè)遠程對象:
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ù)啟動(dòng),按退出..."); 
Console.ReadLine();

3、客戶(hù)端

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

4、運行測試

運行服務(wù)器端和客戶(hù)端,由于監控程序將監視遠程對象的編組進(jìn)程,因此在運行開(kāi)始,就會(huì )顯示遠程對象已經(jīng)被Marshal:

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

一分鐘后,遠程對象一自動(dòng)被Disconnect:

此時(shí)客戶(hù)端如要調用遠程對象一,會(huì )拋出RemotingException異常;

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

align="center">

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

五、結論

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

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

posted on 2004-08-05 16:44 張逸 閱讀(16010) 評論(30)  編輯 收藏 所屬分類(lèi): .NET Remoting

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
博客園 - dudu-快樂(lè )程序員 - 對MarshalByRefObject的講解
C# Remoting的一個(gè)簡(jiǎn)單例子
C# 使用MarshalByRefObject跨程序調用方法
回顧.NET Remoting分布式開(kāi)發(fā)
跟我一起學(xué)WCF(2)
深度管理Remote Objects的生存期
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久