c# - MarshalByRefObject 生命周期

标签 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 的更改,但再次不是 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);

在这种情况下,唯一重要的是保留对目标(显而易见)和赞助商的引用。 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 来处理这个问题。

关于c# - MarshalByRefObject 生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26280030/

相关文章:

c# - c#从串口读取字符

c# - 验证 ASP.Net 文本框不为空但允许空格?

asp.net - 从 VB.NET 配置 ChartJS

remoting - 使用 Akka 启动多个远程服务器

java - 如何在 Flex/BlazeDS 中同时支持 HTTP 和 HTTPS channel ?

.net - 关闭 .net JIT 编译器优化

c# - 将列表(对象)转换为列表(字符串)

c# - 无论如何在 C# 中获取所有文件名而没有异常(exception)?

c# - asp.net中不同时区的日期随机变化

vb.net - DataGridView - 如何隐藏 "new"行?