Объркване на .NET AppDomain

Не успях да намеря много ясно описание на това, което се случва при използване на AppDomains, така че се надявам, че някой ще може да ме просветли. Имам проста тестова програма (в общи линии изтръгната от примера за MSDN):

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 : local
В AppDomain NewDomain

И така... когато направя remote.PrintA(localA), това включва ли маршалинг? Разглеждането на IL в Reflector предполага, че не, но си помислих, че данните в един AppDomain нямат достъп до данни от друг AppDomain.

Ако премахна : MarshalByRefObject от декларацията на A, програмата отпечатва

В AppDomain test.exe
В AppDomain test.exe
A : локален
В AppDomain test.exe

Какво се случва в този случай? Създава ли се нов AppDomain?


person Graham Clark    schedule 18.11.2010    source източник


Отговори (1)


Поведението, което виждате, е съвсем нормално.

Ако премахнете MarshalByRefObject, тъй като имате атрибут Serializable, отдалеченото ще сериализира класа вместо вас и ще маршалира състоянието към основния AppDomain. Така че, когато методът се изпълнява, се изпълнява в текущия AppDomain, тъй като живее в основния AppDOmain (е сериализиран и маршалиран към текущия AppDomain).

Ако запазите MarshalByRefObject, отдалеченото ще направи повикването на отдалечения обект.

Ако премахнете и двете, това ще изведе изключение, тъй като отдалечените обекти трябва да имат такова.

person Aliostad    schedule 18.11.2010
comment
Argghhh, разсеях се и забравих да натисна изпращане :) - person leppie; 18.11.2010
comment
Добре благодаря. Така че, ако оставите MarshalByRefObject и промените отдалечения обект, тези промени маршалирани ли са към AppDomain? Също така, защо бихте оставили MarshalByRefObject? Това осигурява ли полза в някои сценарии? - person Graham Clark; 18.11.2010
comment
Обикновено бихте използвали само един, ако използвате и двата, MarshalByRefObject ще влезе в сила. Всичко това са отдалечени неща (преди WCF), които вече са доста стари, но все още се използват за комуникация между AppDomain. Може да искате да прочетете за Отдалечено управление, ако имате нужда от повече информация. Отговорът на въпроса ви е да, можете да манипулирате обекти, като използвате отдалечено управление на различни AppDomains, процеси или машини. - person Aliostad; 18.11.2010