2010-11-18 4 views
2

Мне не удалось найти очень четкое описание того, что происходит при использовании AppDomains, поэтому, надеюсь, кто-то сможет просветить меня. У меня есть простой тестовой программы (в основном сорваны 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); 
    } 
} 

При запуске, это печатает

В AppDomain TEST.exe
В AppDomain NewDomain
A: местный
В AppDomain NewDomain

Итак ... когда я делаю remote.PrintA(localA), do это связано с сортировкой? Глядя на IL в Reflector, нет, но я думал, что данные в одном AppDomain не могут получить доступ к данным из другого AppDomain.

Если удалить : MarshalByRefObject из декларации A, программа печатает

В AppDomain TEST.exe
В AppDomain TEST.exe
A: местный
В AppDomain TEST.exe

Что происходит в этом случае? Создается ли новый AppDomain?

ответ

3

Поведение, которое вы видите, вполне нормально.

Если удалить MarshalByRefObject, поскольку у вас есть Serializable атрибута, Remoting будет сериализовать класс для вас и маршалинга состояния к основному AppDomain. Поэтому, когда этот метод работает, он запускается в текущем AppDomain, так как он живет в основном AppDOmain (был сериализован и настроен на текущий AppDomain).

Если вы держите MarshalByRefObject, удаленный вызов вызовет удаленный объект.

Если вы удалите оба, это вызовет исключение, так как удаленные объекты должны иметь один.

+0

Argghhh, отвлекся и забыл нажать submit :) – leppie

+0

Хорошо, спасибо. Итак, если вы оставите «MarshalByRefObject» и мутируете «удаленный» объект, изменились ли эти изменения на AppDomain? Кроме того, почему вы оставите «MarshalByRefObject»? Получает ли это преимущество в некоторых сценариях? –

+1

Обычно вы используете только один, если вы используете оба MarshalByRefObject, вступают в силу. Это все удаляет вещи (Pre-WCF), которые сейчас довольно старые, но все еще используются для связи между приложениями. Вы можете прочитать о Remoting, если вам нужна дополнительная информация. Ответ на ваш вопрос - да, вы можете манипулировать объектами, используя удаленный доступ к различным приложениям, процессам или машинам. – Aliostad

Смежные вопросы