.net AppDomain仅部分遵守InitializeLifetimeService(如果有)

.net AppDomain仅部分遵守InitializeLifetimeService(如果有),.net,vb.net,marshalling,appdomain,object-lifetime,.net,Vb.net,Marshalling,Appdomain,Object Lifetime,多亏了Timiz0r,我已经解决了这个问题,但它是多步骤的,所以我在这里详细介绍了完整的解决方案;原始问题如下。首先,我将ILS功能更改为: Public Overrides Function InitializeLifetimeService() As Object Return Nothing End Function 然后我把它包括在我的程序中以及A中。正如Timiz0r指出的,表单继承MarshalByRefObject,因此我不必在我的主类(已经继承了表单)中包含inheri

多亏了Timiz0r,我已经解决了这个问题,但它是多步骤的,所以我在这里详细介绍了完整的解决方案;原始问题如下。首先,我将ILS功能更改为:

Public Overrides Function InitializeLifetimeService() As Object
    Return Nothing
End Function
然后我把它包括在我的程序中以及A中。正如Timiz0r指出的,表单继承MarshalByRefObject,因此我不必在我的主类(已经继承了表单)中包含inherits语句。这是一件大事,因为我最初没有包括它。接下来,我将AppDomain设置更改为:

Dim _ADomain As AppDomain = AppDomain.CreateDomain(Name)
Dim item As New A
item = CType(_ADomain.CreateInstanceAndUnwrap(GetType(A).Assembly.FullName, GetType(A).FullName), A)
通过这些更改,我现在可以根据需要使用DLL COM对象的单独实例

原始问题
我正在编写一个应用程序,它创建一个对象列表,每个对象都引用一个DLL,每个对象都放在自己的AppDomain中,以防止DLL实例相互干扰。换一种方式:

  • 程序维护一个列表(a)
  • A使用CreateInstanceAndUnwrap创建为AppDomain的实例
  • 每个A都引用mirror.dll,它包含在应用程序的引用中
  • 所有这些都很好,但在设置域时,对InitializeLifetimeService的调用不受尊重。。。有点在等待默认的5分钟并调用我的一个a之后,我得到了RemoteException错误。然而,在加入一些Try/Catch语句后,我发现我可以找到有问题的A,但当它试图引发事件时,它失败了。此外,DLL对象本身似乎已被删除(或者在尝试RaiseEvent时也会失败,这是经常发生的)

    ,AppDomain中的覆盖将自动创建一个不会过期的租约。所以我试着这样做:

    _ADomain = AppDomain.CreateDomain(Name)
    _ADomain.InitializeLifetimeService()
    Dim item As A
    item = CType(_ADomain.CreateInstanceAndUnwrap(GetType(A).Assembly.FullName, GetType(A).FullName), A)
    
    没有骰子。根据,重写InitializeLifetimeService并不返回任何内容将做同样的事情。因此,在A类中,我做:

    <SecurityPermissionAttribute(SecurityAction.Demand, _
                                     Flags:=SecurityPermissionFlag.Infrastructure)> _
    Public Overrides Function InitializeLifetimeService() As Object
        Return Nothing
    End Function
    
    _
    公共重写函数InitializeLifetimeService()作为对象
    一无所获
    端函数
    
    然而,一切都没有发生。所以,顺便说一下,我试着设定一个长期租约:

    <SecurityPermissionAttribute(SecurityAction.Demand, _
                                     Flags:=SecurityPermissionFlag.Infrastructure)> _
    Public Overrides Function InitializeLifetimeService() As Object
        Dim lease As ILease = CType(MyBase.InitializeLifetimeService(), ILease)
        If lease.CurrentState = LeaseState.Initial Then
            lease.InitialLeaseTime = TimeSpan.FromDays(5)
            lease.SponsorshipTimeout = TimeSpan.FromDays(5)
            lease.RenewOnCallTime = TimeSpan.FromDays(5)
        End If
        Return lease
    End Function
    
    _
    公共重写函数InitializeLifetimeService()作为对象
    作为ILease=CType(MyBase.InitializeLifetimeService(),ILease)的Dim租约
    如果lease.CurrentState=leaseEstate.Initial,则
    lease.InitialLeaseTime=TimeSpan.FromDays(5)
    lease.SponsorshipTimeout=TimeSpan.FromDays(5)
    lease.RenewaonCallTime=TimeSpan.FromDays(5)
    如果结束
    退租
    端函数
    
    这个问题的部分原因似乎是我在初始状态下从来没有得到过A。但是如果我使用以前的设置并且总是不返回任何内容,那么这应该不是问题,对吗?不幸的是,在做这类事情的例子中几乎没有什么,所以我很可能做错了什么。我全神贯注于我应该如何处理这个问题,如果我不能克服这个问题,整个项目将一事无成

    我可能应该提到(第三方、封闭源代码)DLL不可序列化,并且极不可能继承MarshallByRefObject。这就是为什么我将类放入AppDomain而不是DLL,但这可能是问题的一部分


    可能是相关的,但设置与我正在做的不同,它是针对C#,我在转换为VB时遇到了一些问题。

    我已经有一段时间没有实现类似的东西了,但我认为您需要有
    a
    ,以及带有事件处理程序的类,从
    MarshalByRefObject
    继承,并提供一个不会过期的
    ILease

    另外,为了防止在进行上述更改后,
    InitializeLifetimeService
    方法中返回null不起作用,下面是我用来提供非过期ILease的代码:

    Public Overrides Function InitializeLifetimeService() As Object
        Dim lease As ILease = DirectCast(MyBase.InitializeLifetimeService(), ILease)
        If lease.CurrentState = LeaseState.Initial Then
            lease.InitialLeaseTime = TimeSpan.Zero
        End If
        Return lease
    End Function
    

    我不记得为什么我使用上面的代码而不返回null。不过,我想我会提供它以防万一。

    我已经有一段时间没有实现类似的东西了,但我认为您需要有
    a
    ,以及带有事件处理程序的类,从
    MarshalByRefObject
    继承,并提供一个不会过期的
    ILease

    另外,为了防止在进行上述更改后,
    InitializeLifetimeService
    方法中返回null不起作用,下面是我用来提供非过期ILease的代码:

    Public Overrides Function InitializeLifetimeService() As Object
        Dim lease As ILease = DirectCast(MyBase.InitializeLifetimeService(), ILease)
        If lease.CurrentState = LeaseState.Initial Then
            lease.InitialLeaseTime = TimeSpan.Zero
        End If
        Return lease
    End Function
    

    我不记得为什么我使用上面的代码而不返回null。不过,我想我会提供它以防万一。

    调用A的类是主窗体,我尝试继承MarshallByRefObject,结果得到一个错误,即基类“不能与基类不同”System.Windows.Forms.form是它的其他部分类型之一“幸运的是,
    表单
    继承自
    MarshalByRefObject
    。我不知道这一点。但是如果它继承了,那么主类不应该已经有了必要的设置吗?或者我需要做一些额外的事情来应用它吗?只要继续并覆盖
    InitializeLifetimeService
    ,希望我不必因为这个答案不正确而删除它:事实上,这就是我必须做的。我做了一些其他的改变,我会更新我的主要帖子来传达我所做的事情。谢谢你的帮助!调用A的类是主窗体,我尝试继承MarshalByRefObject,但得到的错误是,基类“不能与基类不同”System.Windows.Forms.form是它的其他部分类型之一“幸运的是,
    表单
    继承自
    MarshalByRefObject
    。我不知道这一点。但是如果它继承了,那么主类不应该已经有了必要的设置吗?或者我需要做一些额外的事情来应用它吗?只要继续并覆盖
    InitializeLifetimeService
    ,希望我不必删除这个答案