Domanda

Sono incuriosito dalla questa risposta da un'altra discussione SO, e Speravo che qualcuno potesse aiutarmi a far luce sul concetto.

Supponi di avere un AppDomain primario e un gruppo di AppDomain figlio, creati e inizializzati da AppDomain primario. In pseudo codice:

Principale AppDomain:

class Parent
{
    public void InitChildren(IList<ChildInfo> children)
    {
        foreach (var childInfo in children)
        {
            var ad = CreateNewChildAppDomain();
            var child = (Child)ad.CreateInstanceAndUnwrap(typeof(Child));
            child.Init(this);
        }
    }

    public void Register(BasePoco info)
    {
        // Do something with info.
    }
}

Child AppDomain:

class Child : MarshalByRefObject
{
    public void Init(Parent parent)
    {
        parent.Register(new Container<MyInfo>(new MyInfo()));
    }
}

class MyInfo : BasePoco // <- not a MarshalByRefObject!
{
    public MyInfo() { ... }
}

Durante Init (), AppDomain figlio crea un'istanza di un oggetto POCO, che per definizione non è marshallabile. Supponiamo anche che non possiamo modificarlo al riguardo.

La risposta collegata suggerisce che racchiudendolo in un Container<T> (che è marshalable) dovrebbe consentirne il ritorno ad AppDomain primario. Lo capisco perché è il proxy a Container<MyInfo> istanza che viene realmente passato.

Quello che non capisco è come l'AppDomain primario può eventualmente accedere all'istanza POCO nel contenitore tramite il proxy del contenitore . Vedo l'operatore di cast implicito sovraccarico in <=> e capisco che restituisce l'istanza POCO contenuta. Ma quell'istanza non viene sottoposta a proxy stesso: è ancora in AppDomain figlio! Quindi, questa pausa non dovrebbe?

Cosa sta succedendo davvero qui?

È stato utile?

Soluzione

Non appena il contenitore restituisce l'istanza residente nell'altro AppDomain (indipendentemente dal fatto che ciò avvenga tramite la proprietà Value o l'operatore di conversione implicita), l'oggetto verrà sottoposto a marshalling. Se si tratta di un MarshalByRefObject, verrà generato un nuovo proxy in modo che tu possa accedervi. In caso contrario, l'oggetto verrà copiato (suddiviso per valore, serializzato) nel dominio dell'applicazione corrente.

L'unica cosa con cui la classe Container mostrata in quella domanda può aiutare è se vuoi mantenere un proxy su un altro oggetto che non dovrebbe essere messo in marshalling. Ma in questo caso, non è necessario accedere alla proprietà Value o utilizzare l'operatore di conversione implicita da AppDomain in cui risiede il proxy, poiché ciò causerebbe il marshalling dell'oggetto nel contenitore. Tuttavia, è possibile utilizzare il contenitore come argomento in un metodo su un oggetto che vive nello stesso AppDomain dell'oggetto Container, consentendo quindi sostanzialmente di mantenere un riferimento a un oggetto non marshallabile (non serializzabile e non MarshalByRef o di un tipo in un assembly che non può essere caricato su AppDomain con il proxy ecc.) e passarlo come un " handle " ;.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top