我有一个.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))


直接更改当前的LeaseTime,但不更改租约的InitialLeaseTime。

最后,我尝试调用共享的(静态)属性LeaseTime,它实际上导致了Lease开头时CurrentLeaseTime的更改,但又不是InitialLeaseTime的更改,InitialLeaseTime似乎在5分钟后结束了,我的远程对象被gc了:

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


感谢您的帮助,
谢谢!

最佳答案

不知道发生了什么,但是它是这样工作的

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
    }
}


完成后,只需在赞助商上将Release设置为true即可。您也可以通过在Sponsor上实现IDisposable来处理此问题(如果您很喜欢)。

10-08 19:54