Sunday, March 19, 2006

Issues when using MarshalByRefObject instances from several application domains

At first let’s consider why we need to inherit our classes from MarshalByRefObject.
The reason is very simple - we want use them in separate application domains.

Let’s suppose we have to appdomains: appdomain1 and appdomain2.
(In this post I will not cover the details of application domain creation)

public class MainAppD : MarshalByRefObject
{
public SlaveAppD slaveAppDomain;
public void DoInPrimaryAppDomain()
{
}
}

//this class will be executing on second app domain
public class SlaveAppD : MarshalByRefObject
{
public MainAppD mainAppDomain;
public void DoInSlaveAppDomain()
{
}
}

What's wrong with these classes?

Recently I had similar scenario, and wondered why did my objects get disconnected from other appdomain.
When object is disconnected and you try to call its methods you get RemotingException...

Let’s consider lifetime of the above mentioned
class members that are references, namely SlaveAppD.slaveAppDomain and MainAppD.mainAppDomain
will become __TransparentProxy references. All calls will go through these transparent proxies.

Notions of proxies and application domains are directly connected with notion lifetime.

If we will consider classes above neither of them cares about its lifetime.
MarshalByRefObject has InitializeLifetimeService() method that returns time lease. The lease specifies
how long this object can be "alive" (Basically this means that proxy connection is alive).
The default lease value is 5 minutes. To increase lifetime
one has to override InitializeLifetimeService. Lets set lease time to 15.

public override Object InitializeLifetimeService()
{
ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial)
{
lease.InitialLeaseTime = TimeSpan.FromMinutes(15);
lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
}
return lease;
}

If you want infinite proxy connection lifetime the you simply return null.

//Infinite lifetime lease
public override Object InitializeLifetimeService()
{
return null;
}

No comments:

Post a Comment