| home / programming / csharp / webservices / chap6 / 2 | [previous] [next] |
|
Let's compare .NET Remoting leasing again with the leasing of cars. If someone pays for the lease
of the car, they are a sponsor. We have sponsors with .NET Remoting, too. If we don't want to rely on
the client to invoke methods to extend the lifetime, we can use a sponsor. Using a sponsor is a
good way to have long-running objects where we don't know how long the object will be needed for, or
when the time intervals at which the client makes calls to the object are unforeseeable. The sponsor
can extend the lease of the remote object. If the leasing time is expired, the sponsor is
asked if it extends the lease. The default time until a call to a sponsor is timed out is defined
with the SponsorshipTimeout option. If that time is reached, another sponsor can be
asked. The option LeaseManagerPollTime defines the time the sponsor has to return a lease
time extension.
The default values for the lease configuration options are listed in this table:
| Lease Configuration | Default Value (seconds) |
leaseTime | 300 |
renewOnCallTime | 120 |
sponsorshipTimeout | 120 |
leaseManagerPollTime | 10 |
There are several methods available to change the options for lifetime services. With the
System.Runtime.Remoting.Lifetime.LifetimeServices class we can set default leasing time
options that are valid for all objects in the application domain using static properties of
this class.
We can also write the lifetime configuration in the application configuration file of the
server. This way this configuration is valid for the complete application. For the application
configuration file we have the <lifetime> tag where leaseTime,
sponsorshipTimeout, renewOnCallTime, and pollTime can be
configured using attributes:
<configuration>
<system.runtime.remoting>
<application name="SimpleServer">
<lifetime
leaseTime = "15M"
sponsorshipTimeOut = "4M"
renewOnCallTime = "3M"
pollTime = "30S" />
</application>
</system.runtime.remoting>
</configuration>
Setting the lifetime options in the configuration file is useful if we want to have the same
lifetime management for all objects of the server. If we have remote objects with different lifetime
requirements, it would be better to set the lifetime for the object programmatically. In the remote
object class we can override the method InitializeLifetimeService() as we can see in the
following example. The method InitializeLifetimeService() of the base class
MarshalByRefObject returns a reference to the ILease interface that can be
used to change the default values. Changing the values is only possible as long as the lease has not
been activated, so that's why we check for the current state to compare it with the enumeration value
LeaseState.Initial. We set the InitialLeaseTime to the very short value of
one minute and the RenewOnCallTime to 20 seconds so that we soon see the results of
the new behavior in the client application:
// MyRemoteObject.cs
using System;
using System.Runtime.Remoting.Lifetime;
namespace Wrox.Samples
{
public class MyRemoteObject : System.MarshalByRefObject
{
public MyRemoteObject(int state)
{
Console.WriteLine("Constructor called");
this.state = state;
}
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;
}
private int state;
public int State
{
get
{
return state;
}
set
{
state = value;
}
}
public string Hello()
{
Console.WriteLine("Hello called");
return "Hello, .NET Client!";
}
}
I'm changing the client code a little bit so that we can see the effects of the lease time. After
the remote object is created, we do a loop five times to call the helper method DisplayLease()
before we sleep for 20 seconds. The method DisplayLease() gets the ILease
interface of the remote object by calling the method GetLifetimeService(). No exception is
thrown if the object that is returned from GetLifetimeService() is not a ILease
interface. This can be the case if the remote object is a well-known type that doesn't support the
leasing mechanism. Calling the property CurrentLeaseTime we access the actual value of
the lease to display it in the console.
// SimpleClient.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Lifetime;
using System.Threading;
namespace Wrox.Samples
{
class SimpleClient
{
static void Main(string[] args)
{
try
{
RemotingConfiguration.Configure("SimpleClient.exe.config");
MyRemoteObject obj = new MyRemoteObject(33);
for (int i=0; i < 5; i++)
{
DisplayLease("In loop: " + i, obj);
Thread.Sleep(20000);
}
Thread.Sleep(30000);
obj.Hello();
}
catch(RemotingException ex)
{
Console.WriteLine(ex.Message);
}
}
public static void DisplayLease(string s, MarshalByRefObject o)
{
ILease lease = o.GetLifetimeService() as ILease;
if (lease != null)
{
Console.WriteLine(s + " - remaining lease time: " +
lease.CurrentLeaseTime);
}
}
}
}
Running the client application we now see the displays from the loop. The initial lifetime of the
remote object is nearly 60 seconds because we have set the InitialLeaseTime property to
one minute. The lifetime is reduced with the following loops. Starting with loop number two, the
lifetime remains constant with 20 seconds. This is because we have set the RenewOnCallTime
property to 20 seconds. Every time we ask for the current value of the lifetime we do a new call on
the remote object, so the lease time is set to 20 seconds. After we exit the loop we wait another 30
seconds, and this time the remote object is already garbage-collected because the lifetime has been
exceeded, so we get a RemotingException the next time we call a method:

| home / programming / csharp / webservices / chap6 / 2 | [previous] [next] |
Created: February 25, 2002
Revised: February 25, 2002
URL: http://webreference.com/programming/csharp/webservices/chap6/2/6.html