首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 操作系统
Microsoft .Net Remoting系列专题之二:Marshal、Disconnect与生命周期以及跟踪服务-.NET教程,.NET Framework
作者:网友供稿 点击:72
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 

一、远程对象的激活

在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:

然后再客户端调用这两个远程对象的printstring方法,服务器端接受字符串:

一分钟后,远程对象一自动被disconnect:

此时客户端如要调用远程对象一,会抛出remotingexception异常;

又一分钟后,远程对象二被disconnect了:

align="center">

用户还可以根据这个代码测试renewoncalltime的时间是否正确。也即是说,在对象还未被disconnect时,调用对象,则从调用对象的这一刻起,其生命周期不再是原来设定的初始有效时间值(initialleasetime),而是租用更新时间值(renewoncalltime)。另外,如果这两个远程对象没有重写initializelifetimeservice方法,则生命周期应为租用管理器所设定的值,为永久有效(设置为0)。那么这两个对象不会被自动disconnect,除非我们显式指定关闭它的连接。当然,如果我们显式关闭连接,跟踪程序仍然会监视到它的变化,然后显示出来。

五、结论

通过我们的测试,其实结论已经很明显了。通过marshal编组的对象要受到租用的生命周期所控制。注意对象被disconnect,并不是指这个对象被gc回收,而是指这个对象保存在通道的相关代理信息被断开了,而对象本身仍然在服务器端存在。

所以我们通过remoting提供服务,应根据实际情况指定远程对象的生命周期,如果不指定,则为remoting默认的设定。要让所有的远程对象永久有效,可以通过配置文件或租用管理器将初始有效时间设为0。



文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·在.Net中嵌入资源文件到程序集中-.NET教程,VB.Net语言
·字符串转换成十六进制-.NET教程,算法/线程
·获得网卡MAC地址和IP地址(VB.net)-.NET教程,VB.Net语言
·.Net框架程序设计(一)----进阶-.NET教程,.NET Framework
·我是否可以将Excel数据导入?-ASP教程,数据库相关
·封面的最佳设计-.NET教程,评论及其它
·使用C#控制远程计算机的服务-.NET教程,C#语言
·利用XMLHTTP下载文件-ASP教程,XML相关
·关于VB.net中无法使用VB6控件-.NET教程,VB.Net语言
·.NET里面的Interop太烂了-.NET教程,.NET Framework
最新文章
·windowsxp sp3 概览里面到底有什么?_windows xp
·让vista系统停止讨厌的报告程序问题_windows vista
·如果你有100万流量如何赚钱_网赚技巧
·携程海归派ceo梁建章:天才整合旅游业_站长访谈
·狂热+坚持=成功 博客园ceo dudu访谈_站长访谈
·php5对mysql5的任意数据库表的管理代码示例(三) _php技巧
·php5对mysql5的任意数据库表的管理代码示例(一)_php技巧
·好的产品才是最好的推广_站长心得
·视频网站的媒体传播现状走向_站长心得
·点评一下目前国内各站长类网站发展现状_站长心得
相关主题
  • microsoft exchange 2000 server的internet配置_exchange server
  • microsoft smtp 服务器在第三方测试中可能显示为能够接受并中继电子邮件_exchange server
  • microsoft exchange server 2003的探讨_exchange server
  • microsoft exchange 2000 群集_exchange server
  • microsoft exchange 邮箱合并程序 (exmerge.exe) 信息_exchange server
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭