Question

Thanks to Timiz0r, I've solved this issue, but it's multi-step so I'm detailing the full solution here; the original question is below. First, I changed my ILS function to be simply:

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

Then I included this in my Program as well as A. As Timiz0r pointed out, Form inherits MarshalByRefObject, so I didn't have to include a Inherits statement on my main class (which already inherited Form). This was the big thing, because I didn't include it originally. Next, I changed my AppDomain setup to be:

Dim _ADomain As AppDomain = AppDomain.CreateDomain(Name)
Dim item As New A
item = CType(_ADomain.CreateInstanceAndUnwrap(GetType(A).Assembly.FullName, GetType(A).FullName), A)

With these changes I can now use separate instances of the DLL COM object as desired.

Original Question


I am writing an application that creates a list of objects, each referring to a DLL, and each object placed in its own AppDomain to keep the instances of the DLL from interfering with each other. Taken another way:

  1. Program maintains a List(Of A)
  2. A is created as an instance of AppDomain using CreateInstanceAndUnwrap
  3. Each A refers to mirror.dll, which is including in the application's references

All of this is fine and dandy except that when setting up the Domain, the call to InitializeLifetimeService is not respected... kind of. After waiting the default 5 minutes and making a call to one of my A's, I get the RemoteException error. However, putting in some Try/Catch statements I discovered that I can reach the A in question, but it fails when it tries to RaiseEvent. In addition, it seems that the DLL object itself is dropped (or it also fails when trying to RaiseEvent, which it does often).

According to this article, the override in AppDomain should automatically create a lease that doesn't expire. So I try this:

_ADomain = AppDomain.CreateDomain(Name)
_ADomain.InitializeLifetimeService()
Dim item As A
item = CType(_ADomain.CreateInstanceAndUnwrap(GetType(A).Assembly.FullName, GetType(A).FullName), A)

No dice. According to another MSDN article, overriding InitializeLifetimeService and returning Nothing will do the same thing. So, within the A Class, I do:

<SecurityPermissionAttribute(SecurityAction.Demand, _
                                 Flags:=SecurityPermissionFlag.Infrastructure)> _
Public Overrides Function InitializeLifetimeService() As Object
    Return Nothing
End Function

Yet again, nothing happens. So, going by yet another article, I try to just set a long lease:

<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

Part of the problem for this seems to be that I never get A in the Initial state. But that shouldn't be an issue if I use the previous setup and always return Nothing, right? Unfortunately, there's very little out there in the way of examples for doing this kind of thing, so I may well be doing something wrong. I'm all ears for how I should approach this, the entire project is for naught if I can't get over this problem.

I should probably mention that the (third party, closed source) DLL is not serializable and is highly unlikely to inherit MarshalByRefObject. This is why I put the class into the AppDomain and not the DLL, but may be part of the problem.

This question might be related, but the setup is different from what I'm doing and it's for C#, which I'm having a tad trouble converting to VB in my head.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top