Remoting方面的转帖2
三、跟踪服务   
    
  如前所述,我们要判断通过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服务启动,按<Enter>退出...");     
  Console.ReadLine();   
    
  3、客户端   
    
  通过Activator.GetObject()获得两个远程对象,并调用其方法PrintString。代码略。   
    
  4、运行测试:   
    
  运行服务器端和客户端,由于监控程序将监视远程对象的编组进程,因此在运行开始,就会显示远程对象已经被Marshal:   
    
    
  (截图的时候出了问题,重新启动了应用程序,所以时间有点差异)   
    
  然后再客户端调用这两个远程对象的PrintString方法,服务器端接受字符串:   
    
  一分钟后,远程对象一自动被Disconnect:   
    
  此时客户端如要调用远程对象一,会抛出RemotingException异常;   
  又一分钟后,远程对象二被Disconnect了:   
    
  用户还可以根据这个代码测试RenewOnCallTime的时间是否正确。也即是说,在对象还未被Disconnect时,调用对象,则从调用对象的这一刻起,其生命周期不再是原来设定的初始有效时间值(InitialLeaseTime),而是租用更新时间值(RenewOnCallTime)。另外,如果这两个远程对象没有重写InitializeLifetimeService方法,则生命周期应为租用管理器所设定的值,为永久有效(设置为0)。那么这两个对象不会被自动Disconnect,除非我们显式指定关闭它的连接。当然,如果我们显式关闭连接,跟踪程序仍然会监视到它的变化,然后显示出来。   
    
  五、结论   
    
  通过我们的测试,其实结论已经很明显了。通过Marshal编组的对象要受到租用的生命周期所控制。注意对象被Disconnect,并不是指这个对象被GC回收,而是指这个对象保存在通道的相关代理信息被断开了,而对象本身仍然在服务器端存在。   
    
  所以我们通过Remoting提供服务,应根据实际情况指定远程对象的生命周期,如果不指定,则为Remoting默认的设定。要让所有的远程对象永久有效,可以通过配置文件或租用管理器将初始有效时间设为0。   
posted on 2010-02-21 15:39 gds通用软件开发系统 阅读(197) 评论(0) 收藏 举报
 
                    
                     
                    
                 
                    
                 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号