MarshalByRefObject终身

时间:2014-10-09 13:42:46

标签: c# vb.net remoting appdomain object-lifetime

我有一个.net WinForms应用程序,它将插件(dll)加载到他们自己的AppDomain中,每个dll都使用domain.CreateInstanceAndUnwrap()获取自己的AppDomain。我想要的是,这些对象永远保持连接(直到应用程序停止) InitialLeaseTime是5分钟,但我无法找到改变它的方法。 .. 我尝试覆盖远程对象的InitializeLifetimeService():

Public Overrides Function InitializeLifetimeService() As Object  
     Return Nothing  
End Function

这里我得到一个Typeload-Exception,说这会破坏继承规则。 添加

<SecurityPermissionAttribute(SecurityAction.Demand, Flags:=SecurityPermissionFlag.Infrastructure)>
<SecuritySafeCritical>

不会改变任何事情。

然后:

Dim tmpObj As Object = domain.CreateInstanceAndUnwrap(type.AssemblyName, type.TypeName)
Dim tmpRemote As tmpRemoteType = CType(tmpObj, tmpRemoteType)

Dim lifetimeService As Object = Runtime.Remoting.RemotingServices.GetLifetimeService(tmpRemote)
Dim lease As ILease = TryCast(lifetimeService, ILease)
If (lease IsNot Nothing) Then
     lease.Register(_sponsor)
 End If

不会这样做,因为赞助商的Renewal()方法(此处未显示)不会被调用。

致电

lease.Renew(TimeSpan.FromMinutes(300))

直接更改CurrentLeaseTime,但不更改租约的InitialLeaseTime。

最后我尝试调用共享(静态)属性LeaseTime,这实际上导致了租约开始时CurrentLeaseTime的更改,但再次 NOT InitialLeaseTime,它似乎在5分钟后结束我的远程对象是gc&#39; ed:

LifetimeServices.RenewOnCallTime = System.TimeSpan.FromMinutes(300)

感谢任何帮助, THX!

1 个答案:

答案 0 :(得分:2)

不确定发生了什么,但这里的工作方式

var sponsor = new Sponsor();  // manages lifetime of the object in otherDomain
var target = otherDomain.CreateInstanceFromAndUnwrap(assemblyFilename, typeFullName) 
    as MarshalByRefObject;

var lease = target.InitializeLifetimeService() as ILease;
lease.Register(sponsor);

在这种情况下,您必须保留对目标(明显)和赞助商的引用。赞助商是一个管理订阅的类:

class Sponsor : MarshalByRefObject, ISponsor
{
    public bool Release { get; set; }

    public TimeSpan Renewal(ILease lease)
    {
        // if any of these cases is true
        if (lease == null || lease.CurrentState != LeaseState.Renewing || Release)
            return TimeSpan.Zero; // don't renew
        return TimeSpan.FromSeconds(1); // renew for a second, or however long u want
    }
}

当您完成它之后,只需将赞助商的发布设置为true即可。您也可以通过在赞助商上实施IDisposable来处理这个问题,如果这让您感到满意。