2010-11-18 119 views
2

我一直无法找到使用AppDomain时发生了什么的非常清晰的描述,所以希望有人能够启发我。我有一个简单的测试程序(基本上扯掉MSDN example):.NET AppDomain混淆

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); 
    } 
} 

运行时,该打印出

在AppDomain中的test.exe
在AppDomain中NEWDOMAIN
答:当地
AppDomain NewDomain

所以...当我做remote.PrintA(localA),do这涉及到编组?在Reflector中查看IL建议不,但我认为一个AppDomain中的数据无法访问另一个AppDomain中的数据。

如果我从A声明删除: MarshalByRefObject,该程序将打印

在AppDomain中的test.exe
在AppDomain中的test.exe
答:当地
在AppDomain中的test.exe

在这种情况下发生了什么?是否创建了一个新的AppDomain?

回答

3

您看到的行为非常正常。

如果删除MarshalByRefObject,既然你有Serializable属性,远程将序列化您的类和元帅状态到主AppDomain中。因此,当方法运行时,在当前AppDomain中运行,因为它位于主AppDOmain中(已序列化并编组为当前AppDomain)。

如果您保留MarshalByRefObject,则远程处理将对远程对象进行调用。

如果你删除了两者,它会引发异常,因为远程处理对象需要有一个异常。

+0

argghhh,分心,忘了提交:) – leppie 2010-11-18 10:11:27

+0

好的,谢谢。因此,如果您离开MarshalByRefObject并改变“remote”对象,这些更改是否编组到AppDomain?另外,为什么你会放弃'MarshalByRefObject'?这是否在某些情况下提供了好处? – 2010-11-18 10:18:42

+1

您通常只使用一个,如果您同时使用MarshalByRefObject将会生效。这是所有远程的东西(Pre-WCF),现在已经很老了,但仍然用于AppDomain之间的通信。如果您需要更多信息,您可能需要阅读Remoting。回答你的问题是,你可以在不同的AppDomain,进程或机器上使用远程处理对象。 – Aliostad 2010-11-18 10:29:19