[Remoting专题系列] 四:生存期租约

None.gif Remoting 采取了一种称之为  " 租约 "  的机制来管理远程对象(Singleton、CAO)的生存期策略。每个应用程序域中都有一个租约管理器(LifetimeServices),它负责管理所有参与生存期的远程对象租约。租约管理器定期检查所有租约以确定过期的租约时间,如果租约已过期,将向该对象发起人(Sponsor)的发送请求,查询是否有谁要续订租约,若没有任何发起人续订该租约,租约将被移除,该远程对象也会被删除等待垃圾回收器回收。如果远程对象被发起人多次续订租约或被客户端持续调用,其生存期可以比其生存期租约长得多。
None.gif
None.gif所谓发起人 (Sponsor,MSDN 翻译为
" 主办方 " ,真别扭 ! ) 就是一个或多个与远程对象关联,用于定义租约延长时间的对象。租约管理器通过回调发起人方法(ISponsor.Renewal)来查询是否续订租约。发起人需要继承自 MarshalByRefObject,且必须实现 ISponsor 接口。在 System.Runtime.Remoting.Lifetime 名字空间中,Framework 为我们提供了一个缺省实现 —— ClientSponsor。
None.gif
None.gif租约参数
None.gif当参与生存期管理的远程对象被创建后,其租约被设置为 LifetimeServices.LeaseTime 或 ILease.InitialLeaseTime。
None.gif我们可以通过 ILease.CurrentLeaseTime 来检查对象租约过期的剩余时间。
None.gif客户端调用远程对象方法时,会发生隐式续订租约行为。当 CurrentLeaseTime 小于 RenewOnCallTime,则租约被设置为 RenewOnCallTime。
None.gif租约管理器每隔一定时间(LeaseManagerPollTime)检查一次租约列表,如果某租约过期则通知其发起人,询问是否进行续订。如发起人未能在 SponsorshipTimeout 时间内响应,则移除该主办方并调用另一主办方。如果没有其他主办方,则租约过期,且垃圾回收器将处置该远程对象。
None.gif租约过期试验
None.gif
None.gif
using  System;
None.gif
using  System.Collections;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Reflection;
None.gif
using  System.Threading;
None.gif
using  System.Runtime.Serialization;
None.gif
using  System.Runtime.Serialization.Formatters;
None.gif
using  System.Runtime.Serialization.Formatters.Binary;
None.gif
using  System.Runtime.CompilerServices;
None.gif
using  System.Runtime.Remoting;
None.gif
using  System.Runtime.Remoting.Channels;
None.gif
using  System.Runtime.Remoting.Channels.Tcp;
None.gif
using  System.Runtime.Remoting.Messaging;
None.gif
using  System.Runtime.Remoting.Lifetime;
None.gif
None.gif
namespace  Learn.Library.Remoting
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
public class RemotingTest2
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 远程类型
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class Data : MarshalByRefObject
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      
private Guid guid = Guid.NewGuid();
InBlock.gif
InBlock.gif      
public void Test()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        Console.WriteLine(
"{0} in {1}dot.gif", guid, AppDomain.CurrentDomain.FriendlyName);
InBlock.gif        Console.WriteLine((InitializeLifetimeService() 
as ILease).CurrentLeaseTime);
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 服务器端代码
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    static void Server()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      
// 创建新的应用程序域,以便模拟分布结构。
InBlock.gif
      AppDomain server = AppDomain.CreateDomain("server");
InBlock.gif      server.DoCallBack(
delegate
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        
// 设置缺省生存期
InBlock.gif
        LifetimeServices.LeaseTime = TimeSpan.FromSeconds(1);
InBlock.gif        LifetimeServices.RenewOnCallTime 
= TimeSpan.FromSeconds(1);
InBlock.gif        LifetimeServices.LeaseManagerPollTime 
= TimeSpan.FromSeconds(1);
InBlock.gif        LifetimeServices.SponsorshipTimeout 
= TimeSpan.FromSeconds(1);
InBlock.gif
InBlock.gif        TcpServerChannel channel 
= new TcpServerChannel(801);
InBlock.gif        ChannelServices.RegisterChannel(channel, 
false);
InBlock.gif        RemotingConfiguration.RegisterWellKnownServiceType(
typeof(Data), "data",
InBlock.gif          WellKnownObjectMode.Singleton);
ExpandedSubBlockEnd.gif      }
);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 客户端代码
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    static void Client()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      TcpClientChannel channel 
= new TcpClientChannel();
InBlock.gif      ChannelServices.RegisterChannel(channel, 
false);
InBlock.gif      RemotingConfiguration.RegisterWellKnownClientType(
typeof(Data), "tcp://localhost:801/data");
InBlock.gif
InBlock.gif      
// 创建远程对象并调用其方法
InBlock.gif
      for (int i = 0; i < 3; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        Data data 
= new Data();
InBlock.gif        data.Test();
InBlock.gif        Thread.Sleep(
5000);
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      Server();
InBlock.gif      Client();
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif}

None.gif
None.gif输出:
None.gif6ac6fcb9
- 6a5d - 427b - 92bb - cfdcb2265911  in  serverdot.gif
None.gif
00 : 00 : 00.9899856
None.gif86a1716f
- 1ebd - 47d2 - af80 - e501d20813b9  in  serverdot.gif
None.gif
00 : 00 : 01
None.gif9a1039e0
- fac7 - 4bbb - 80c4 - 0bc7d5c9c2ff  in  serverdot.gif
None.gif
00 : 00 : 01
None.gif
None.gif通过输出结果,我们发现 Singleton MBR 对象过期后重新创建。
None.gif
None.gif初始化租约
None.gif
None.gif
1 . 默认租约:用 LifetimeServices 设置所有对象的默认租约。
None.gif
None.gifLifetimeServices.LeaseTime 
=  TimeSpan.FromSeconds( 1 );
None.gifLifetimeServices.RenewOnCallTime 
=  TimeSpan.FromSeconds( 1 );
None.gifLifetimeServices.LeaseManagerPollTime 
=  TimeSpan.FromSeconds( 1 );
None.gifLifetimeServices.SponsorshipTimeout 
=  TimeSpan.FromSeconds( 1 );
None.gif
None.gif
2 . 自定义租约:重写 MarshalByRefObject.InitializeLifetimeService() 自定义对象租约。当 ILease.CurrentState 属性为 LeaseState.Initial 时,可以设置租约的属性。一旦设置,就不能直接更改它们。
None.gif
None.gif
public   class  Data : MarshalByRefObject
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
public override object InitializeLifetimeService()
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{
InBlock.gif    ILease lease 
= (ILease)base.InitializeLifetimeService();
InBlock.gif    
if (lease.CurrentState == LeaseState.Initial)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      lease.InitialLeaseTime 
= TimeSpan.FromSeconds(1);
InBlock.gif      lease.SponsorshipTimeout 
= TimeSpan.FromSeconds(1);
InBlock.gif      lease.RenewOnCallTime 
= TimeSpan.FromSeconds(2);
ExpandedSubBlockEnd.gif    }

InBlock.gif  
InBlock.gif    
return lease;
ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif}

None.gif
None.gif续订租约
None.gif
None.gif续订租约的方式有:
None.gif隐式续订:在调用远程对象方法时发生。
None.gif显示续订:调用 ILease.Renew()。
None.gif发起租约:通过创建发起人(Sponsor)来延长租约。
None.gif在客户端调用 ILease.Renew() 显示续订租约,如果 CurrentLeaseTime 小于续订时间,则租约时间被设置为续订时间。
None.gif
None.gif
static   void  Client()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
// 创建并注册信道
InBlock.gif
  TcpClientChannel channel = new TcpClientChannel();
InBlock.gif  ChannelServices.RegisterChannel(channel, 
false);
InBlock.gif
InBlock.gif  
// 注册远程对象
InBlock.gif
  RemotingConfiguration.RegisterWellKnownClientType(typeof(Data), "tcp://localhost:801/data");
InBlock.gif
InBlock.gif  
// 创建远程对象并调用其方法
InBlock.gif
  Data data = new Data();
InBlock.gif  (data.GetLifetimeService() 
as ILease).Renew(TimeSpan.FromSeconds(100));
ExpandedBlockEnd.gif}

None.gif

转载于:https://www.cnblogs.com/nbwzy/archive/2007/06/05/771573.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值