.NET Remoting Lifetime Management with Leasing and Sponsorship

本文探讨了远程对象生命周期管理中赞助的概念,介绍如何通过定制赞助商类来控制远程对象的生存时间,包括赞助商的注册与注销过程。
3. Sponsorship
As mentioned already, the lifecycle of each remote object is associated with a given lease object. Any remote objects and their associated lease objects are all controlled by lease manager. As the time lapses, the lease’s current lease time decreases, and lease manager will consult the client if it is going to renew the lease when it is equal to zero. Client can take the opportunity to renew the lease by provide a particular sponsor corresponding to the given lease.
It is allowable to make a lease own multiple sponsors. You can create your custom sponsors, letting it implement System.Runtime.Remoting.Lifetime.ISponsor interface which define a Renewal method for you to specify the renewal time. In order to make a particular sponsor associated with a given lease object, you must register it by calling the Register method to the lease. If you do not wan to renew the lease, you can make Renewal method return TimeSpan.Zero or unregister it from the lease by calling the Unregister method to the lease.

public class MySponsor : MarshalByRefObject,ISponsor
{
       public TimeSpan Renewal(ILease lease)
       {
              Debug.Assert(lease.CurrentState == LeaseState.Active);
              //Renew lease by 5 minutes
              return TimeSpan.FromMinutes(5);
       }
}
 
//Create a custom sponsor
ISponsor sponsor = new MySponsor();
MyClass obj = new MyClass();
 
//Register the sponsor
ILease lease = (ILease)RemotingServices.GetLifetimeService(obj);
lease.Register(sponsor);
 
public class MySponsor : MarshalByRefObject,ISponsor
{
       public TimeSpan Renewal(ILease lease)
       {
              Debug.Assert(lease.CurrentState == LeaseState.Active);
              //Refuse to renew lease:
              return TimeSpan.Zero;
       }
}
Marshal-by-Value vs. Marshal -by-Reference
Since sponsor exists in client side application domain, so to its caller, lease manager which resides in server side application domain, it is a remote object. When sponsor is called across application boundaries, it must be marshaled either by reference or by value.
When you make a given sponsor derived from MarshalByRefObject class, it will reside on client side. This can base the decision of renewal time on the client-side properties and event it monitoring. For the marshal-by-reference sponsor, you must register a port with the channel to allow lease manager can call the sponsor callback. In the whole remote object lifetime management process, lease keeps remote object alive, and sponsor keep lease alive. To prevent remote object from being garbage collected, there must be some object to refer the sponsor to avoid making the sponsor destroyed. As a matter of fact, somebody on the client side keep a reference on the sponsor, typically as a class member variable.
If you create a particular sponsor which is just only equipped with a Serializable custom attribute, it will be marshaled to server by value when called. In the case, the sponsor is essentially on server side. Make the sponsor marshaled by value avoid the marshaling overhead of contracting the sponsor. However, on the other hand, it disconnects actually the sponsor from the client and bases its decision on information available on the host's side.
Sample
RemoteServerHost.exe.config: the host configuration file
<?xmlversion="1.0"encoding="utf-8"?>
<?xmlversion="1.0"?>
<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <activatedtype="RemoteServer.MyCAO,ServerAssembly"/>
         </service>
         <channels>
            <channelref="tcp"port="8005">
               <serverProviders>
                  <formatterref="soap"
                    typeFilterLevel="Full"/>
                  <formatterref="binary"
                    typeFilterLevel="Full"/>
               </serverProviders>
            </channel>
         </channels> 
      </application>
   </system.runtime.remoting>
</configuration>
RemoteServerHost.exe: the host application assembly
public class ServerHostDialog : Form
{
       public ServerHostDialog()
       {
              InitializeComponent();
       }
       void InitializeComponent()
       {...}
       static void Main()
       {
              RemotingConfiguration.Configure("RemoteServerHost.exe.config");
              Application.Run(new ServerHostDialog());
       }
}
ServerAssembly class library
namespace RemoteServer
{
       public class MyCAO : MarshalByRefObject
       {
              public void Count()
              {
                     m_Counter++;
                     string appName = AppDomain.CurrentDomain.FriendlyName;
                     MessageBox.Show("Counter value is " +
                            m_Counter.ToString(),appName);
              }     
              int m_Counter = 0;
       }
}
Client.exe.config: the client configuration file
<?xmlversion="1.0"?>
<configuration>
   <system.runtime.remoting>
      <application>
         <clienturl="tcp://localhost:8005">
            <activatedtype="RemoteServer.MyCAO,ServerAssembly"/>
         </client>
         <channels>
            <channelref="tcp"port="0">
               <serverProviders>
                  <formatterref="soap"
                    typeFilterLevel="Full"/>
                  <formatterref="binary"
                    typeFilterLevel="Full"/>
               </serverProviders>
            </channel>
         </channels>
      </application>
   </system.runtime.remoting>
</configuration>
Client EXE assembly
public class MySponsor : MarshalByRefObject,ISponsor
{
       public TimeSpan Renewal(ILease lease)
       {
              Debug.Assert(lease.CurrentState == LeaseState.Active);
              return lease.InitialLeaseTime;
       }
}
 
public class ClientForm : Form
{
       Button m_CallButton;
       ISponsor m_Sponsor;
       MyCAO m_Obj;
 
       public ClientForm()
       {
              InitializeComponent();
 
              m_Sponsor = new MySponsor();
              m_Obj = new MyCAO();
 
              //Register the sponsor
              ILease lease = (ILease)
                     RemotingServices.GetLifetimeService(m_Obj);
              lease.Register(m_Sponsor);
       }
       void InitializeComponent()
       {...}
  
       static void Main()
       {
              RemotingConfiguration.Configure("Client.exe.config");
 
              Application.Run(new ClientForm());
       }
       //Called when the button is clicked
       void OnCall(object sender,EventArgs e)
       {
              m_Obj.Count();
       }
       //Called when the form is closed
       void OnClosed(object sender,EventArgs e)
       {
              //Unegister the sponsor
              ILease lease = (ILease)
                     RemotingServices.GetLifetimeService(m_Obj);
              lease.Unregister(m_Sponsor);
       }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值