灵活管理Remote Objects生存期(lifetime)
Change the Default Lease Time of Remote Objects
.Net Remoting Framework提供了一套完整的机制来管理Server端的Remote Objects的生存期。关于这方面的详细信息,请参考Wayfarer的blog, Microsoft .Net Remoting[高级篇]之一:Marshal、Disconnect与生命周期以及跟踪服务(http://www.cnblogs.com/wayfarer/archive/2004/08/05/30437.aspx ),讲解得非常清楚。
.Net Remoting Framework支持通过配置文件,如web.config,来管理Remote Objects得生存期。如下所示(MSDN):
<lifetime
leaseTime="leasetime"
sponsorshipTimeout="sponsorshipTimeOut"
renewOnCallTime="renewOnCallTime"
leaseManagerPollTime="pollTime"
/>
参数简单解释:
leaseTime - 指定该应用程序的初始租约时间。默认的 leaseTime 为 5 分钟。
SponsorshipTimeout - 指定租约管理器得到租约到期通知时等待主办方响应的时间。如果主办方未能在指定时间内响应,则由垃圾回收器处置该远程对象。默认的 sponsorshipTimeout 为 2 分钟。
RenewOnCallTime - 指定对象上每个函数调用的租约时间的延长时间。默认的 renewOnCallTime 为 2 分钟。
LeaseManagerPollTime - 指定租约管理器在检查到期租约后休眠的时间。默认的 leaseManagerPollTime 为 10 秒。(注:整个application共用一个租约管理器LeaseManager)
虽然使用configuration文件很简单,但是这些设置会对application内的所有Remote Objects起作用,不管你乐意还是不乐意。
这里主要是推荐Ingo Rammer《Advanced .Net Remoting》中提出的管理Remote Objects生存期的方法,通过扩展MarshalByRefObject类来实现灵活调整Remote Objects的生存期。本人觉得在实际应用中蛮有价值,并且非常简单。通过扩展MarshalByRefObject类,可以很好的解决上述问题。
1,扩展MarshalByRefObject类
这样,你不需要让每一个Remote Objects重载MarshalByRefObject.InitializeLifetimeService()方法,并且今后还可以根据需要在ExtendedMBRObject类中添加一些通用的功能。
用法:application内所有MBR的Remote Objects继承ExtendedMBRObject,而不是直接继承MarshalByRefObject类。
简单说明:ExtendedMBRObject重载MarshalByRefObject.InitializeLifetimeService()方法,按Remote Objects的名称来检查configuration文件中appSetting的设置,因此不同的Remote Object可以有不同的生存期参数的设置。如果在appSetting的没有该Remote Object生存期参数的设定,则采用Remoting提供的默认值。如果LeaseTime设置为infinity,则Remote Object生存期为无限时间。
Source code如下(细节方面稍有改动):
==================
using System;
using System.Configuration;
using System.Runtime.Remoting.Lifetime;
namespace ComponentHost
{
public class ExtendedMBRObject: MarshalByRefObject
{
public override object InitializeLifetimeService()
{
string myName = this.GetType().FullName;
string leasetime =
ConfigurationSettings.AppSettings[myName + ".LeaseTime"];
string renewoncall =
ConfigurationSettings.AppSettings[myName + ".RenewOnCallTime"];
string sponsorshiptimeout =
ConfigurationSettings.AppSettings[myName + ".SponsorShipTimeout"];
if (leasetime !=null &&
leasetime.ToLower().Trim() == "infinity")
{
return null;
}
else
{
ILease tmp = (ILease) base.InitializeLifetimeService();
if (tmp.CurrentState == LeaseState.Initial)
{
if (leasetime != null)
{
tmp.InitialLeaseTime =
TimeSpan.FromMilliseconds(Double.Parse(leasetime));
}
if (renewoncall != null)
{
tmp.RenewOnCallTime =
TimeSpan.FromMilliseconds(Double.Parse(renewoncall));
}
if (sponsorshiptimeout != null)
{
tmp.SponsorshipTimeout =
TimeSpan.FromMilliseconds(Double.Parse(sponsorshiptimeout));
}
}
return tmp;
}
}
}
}
2,设置Configuration文件(这里以Web.config为例)
针对需要调整默认生存期的Remote Objects进行配置即可。
<appSettings>
<add key="MyNamespace.MyRemoteObject.LeaseTime" value="5000" />
<add key="MyNamespace.MyRemoteObject.RenewOnCallTime" value="1000" />
<add key="MyNamespace.InfinitelyLivingSingleton.LeaseTime" value="infinity" />
</appSettings>
Reference:
1. Ingo Rammer, Advanced .Net Remoting.
2. Wayfarer, Microsoft .Net Remoting[高级篇]之一:Marshal、Disconnect与生命周期以及跟踪服务, http://www.cnblogs.com/wayfarer/archive/2004/08/05/30437.aspx