2014-10-09 296 views
2

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

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

在这里,我得到一个Typeload的异常,称这将打破继承规则。 添加

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

不会改变任何东西。

然后:

​​3210

不这样做既没有,因为保荐人(这里没有显示)的莫名其妙的更新()方法不会被调用。

调用

lease.Renew(TimeSpan.FromMinutes(300)) 

直接改变CurrentLeaseTime不过租约的不InitialLeaseTime。

最后我打过电话的共享(静态)属性LeaseTime,这实际上导致了在租赁期开始CurrentLeaseTime的变化,但再次的InitialLeaseTime,这似乎是在5分钟后结束,我的远程对象被gc化:

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

任何帮助表示赞赏, Thx!

回答

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来解决这个问题,如果这让您感到尴尬。

+0

嗨,谢谢!使用你的解决方案,赞助商的Renewal()方法现在被调用。但是当我返回TimeSpan.FromHours(1)时,它有时会起作用,有时不起作用。我已经尝试了很多,但无法弄清楚...... btw:lease.CurrentState在续订()内始终处于“活动”状态,而不是“续订”。 – Lukas 2014-10-09 17:53:43

+0

更新:现在工作。我引用了远程对象中的其他对象,这些对象也从MarshalByRefObject继承。这些物体的租赁也必须更新。 – Lukas 2014-10-10 19:17:01