2010-11-18 6 views
2

Je n'ai pas été en mesure de trouver une description très claire de ce qui se passe lors de l'utilisation de AppDomains, donc j'espère que quelqu'un sera en mesure de m'éclairer. J'ai un programme de test simple (essentiellement arraché le MSDN example):.NET AppDomain confusion

using System; 
using System.Reflection; 

class Program 
{ 
    public static void Main(string[] args) 
    {    
     A localA = new A() { Name = "local" }; 
     localA.PrintAppDomain(); 

     AppDomain domain = AppDomain.CreateDomain("NewDomain"); 
     A remoteA = (A)domain.CreateInstanceAndUnwrap(
      Assembly.GetExecutingAssembly().FullName, "A"); 
     remoteA.Name = "remote"; 
     remoteA.PrintAppDomain(); 

     remoteA.PrintA(localA); 
     remoteA.PrintAppDomain(); 
    } 
} 

[Serializable] 
public class A : MarshalByRefObject 
{ 
    public string Name { get; set; } 

    public void PrintAppDomain() 
    { 
     Console.WriteLine("In AppDomain {1}", 
      this.Name, AppDomain.CurrentDomain.FriendlyName); 
    } 

    public void PrintA(A a) 
    { 
     Console.WriteLine(a.ToString()); 
    } 

    public override string ToString() 
    { 
     return String.Format("A : {0}", this.Name); 
    } 
} 

Effectué, ce imprime

Dans AppDomain test.exe
Dans AppDomain NewDomain
A: local
Dans AppDomain NewDomain

Alors ... quand je fais remote.PrintA(localA), faites Est-ce que cela implique le rassemblement? En regardant l'IL dans le réflecteur ne suggère pas, mais je pensais que les données dans un AppDomain ne pouvaient pas accéder aux données d'un autre AppDomain.

Si je retire la : MarshalByRefObject de la déclaration de A, le programme imprime

Dans AppDomain test.exe
Dans AppDomain test.exe
A: local
Dans AppDomain test.exe

Que se passe-t-il dans ce cas? Un nouveau AppDomain est-il créé?

Répondre

3

Le comportement que vous voyez est tout à fait normal.

Si vous supprimez le MarshalByRefObject, puisque vous avez Serializable attribut, Remoting sérialise la classe pour vous et maréchal état au AppDomain principal. Ainsi, lorsque la méthode s'exécute, s'exécute dans l'AppDomain actuel car il réside dans l'AppDOmain principal (a été sérialisé et rassemblé en AppDomain actuel).

Si vous conservez MarshalByRefObject, l'accès distant effectuera l'appel sur l'objet distant.

Si vous supprimez les deux, une exception sera levée car les objets distants doivent en avoir un.

+0

Argghhh, a été distrait et a oublié d'appuyer sur soumettre :) – leppie

+0

Ok, merci. Donc, si vous laissez le 'MarshalByRefObject' et que vous mutez l'objet" remote ", ces changements sont-ils rangés dans l'AppDomain? Aussi, pourquoi abandonneriez-vous 'MarshalByRefObject'? Cela offre-t-il un avantage dans certains scénarios? –

+1

Vous n'en utiliserez normalement qu'un seul, si vous utilisez les deux MarshalByRefObject prendra effet. C'est tout ce qui touche à l'accès distant (Pre-WCF) qui est assez ancien maintenant mais encore utilisé pour la communication inter-AppDomain. Vous pourriez vouloir lire sur Remoting si vous avez besoin de plus d'informations. Réponse à votre question est oui, vous pouvez manipuler des objets en utilisant à distance sur différents AppDomains, processus ou machines. – Aliostad