Working with Lifetime Leases

The garbage collector is responsible for disposing of objects that are no longer being used by active code within a .NET application. Remoted objects present a bit of a dilemma: Which garbage collector is responsible for disposing of the object, and how exactly does the GC know when a remoted object is no longer in use?

Some other distributed systems use what is known as "reference counting" to determine whether an object is ready for disposal. Reference counting over a network can create a lot of network traffic and overhead that only gets worse with the number of clients consuming a given remote object.

What the .NET Framework does is use a lifetime lease. When an MBR (MarshalByRefObject class instance) is created, it is given an initial lease. This lease determines how long the object can remain active without being accessed by clients. If the object's lease runs out, it will be disposed. The next time a remote client accesses a member of the MBR, that remote client will be provided with a new instance of the object.

This behavior can be unexpected and can often cause a lot of problems in production applications. In a testing environment, MBRs often live much longer than they do in production because the remote object is being accessed far more often than in a production environment. When this happens, it is easy for developers to assume that the MBR is always active and is maintaining state properly.

The most common way of customizing the lifetime lease behavior of an MBR is to override the InitializeLifetimeService method on the MarshalByRefObject class. This gives the developer the ability to either create an instance of an object that implements the ILease interface to modify the object's lease properties or to return a null, indicating that the object will live forever ("forever" in this case means until the application hosting the object shuts down).

Take a look at this implementation of InitializeLifetimeService:

public override object InitializeLifetimeService() {     ILease lease = (ILease)base.InitializeLifetimeService();     if (lease.CurrentState == LeaseState.Initial)     {         lease.InitialLeaseTime = TimeSpan.FromMinutes(10);         lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);         lease.RenewOnCallTime = TimeSpan.FromSeconds(10);     }     else if (lease.CurrentState == LeaseState.Renewing)     {         // lease has expired and is requesting to be renewed         lease.Renew(TimeSpan.FromMinutes(1));     }     return lease; } 

In the preceding code, some default values are assigned to the lease when the lease is first being created. A lease is first created when the remoting object is first activated (either by client or server). If the lease has expired and is seeking renewal, the preceding code adds one more minute to the object's lifetime.

If your remote object is stateless and does not need to maintain the values of properties between requests, there is very little need to control the object's lifetime. However, if you have created a Singleton remote object that is maintaining state information such as a list of all connected clients, you might want to grant the object an infinite lifetime by overriding InitializeLifetimeService as follows:

public override object InitializeLifetimeService() {     return null; } 

Object lease management is one of those tasks that are often neglected when creating a remoting application. Awareness of lease lifetimes early in the development process can save you a lot of debugging and troubleshooting when it comes time to deploy the application in a production environment.

Microsoft Visual C# 2005 Unleashed
Microsoft Visual C# 2005 Unleashed
ISBN: 0672327767
EAN: 2147483647
Year: 2004
Pages: 298 © 2008-2017.
If you may any questions please contact us: