Экземпляры статических переменных и домены приложений, что происходит? - PullRequest
23 голосов
/ 21 марта 2012

У меня

public static class A
{
   public static string ConnString;
}

[Serializable]
public class Test{
   // Accesing A's field;
   public string ConnString{get{return A.ConnString;}set{A.ConnString=value;}}
}

void Main()
{
   A.ConnString = "InitialString"; // I set A.ConnString in the current domain

   var newDomain = AppDomain.CreateDomain("DomNew");
   Test TObj = newDomain.CreateInstanceAndUnwrap(typeof(Test).Assembly.FullName, typeof(Test).FullName) as Test ;

   TObj.ConnString = "NewDomainString"; // It is supposed to set A.ConnString in the newDomain aka a different instance of A.ConnString

   // Here it is supposed to print two different values
   Console.WriteLine(A.ConnString);  // "InitialString"
   Console.WriteLine(TObj.ConnString); // "NewDomainString"
}

Но НЕТ!Две строки WriteLines выводят одно и то же значение "NewDomainString"!ПОЧЕМУ ???

этот код

TObj.ConnString = "NewDomainString"

должен изменить строку во вновь созданном домене, но, похоже, они оба ссылаются на один и тот же экземпляр!

Почему, что здесь происходит?

Ответы [ 2 ]

22 голосов
/ 21 марта 2012

Существует только два способа доступа к классу из другого AppDomain: один - это класс [Serializable], как у вашего класса Test, другой - если класс наследует от MarshalByRefObject .Поскольку ваш класс является сериализуемым, его копия создается для каждого кросс-доменного вызова.Таким образом, Test, который получает основной домен приложения при вызове ...

Test TObj = newDomain.CreateInstanceAndUnwrap(typeof(Test).Assembly.FullName, typeof(Test).FullName) as Test;

, на самом деле не является экземпляром Test, созданным в домене приложений DomNew, - это копия, локальная для основного"AppDomain и, следовательно, ссылается на статические переменные из" основного "AppDomain.

Если вы хотите, чтобы Test демонстрировал ожидаемое поведение, сделайте его наследником от MarshalByRefObject вместо того, чтобы быть сериализуемым.

12 голосов
/ 21 марта 2012

Вы пометили свой Тестовый класс как Сериализуемый.Это не верно.Вы должны были получить от MarshalByRef.В противном случае TObj будет просто локальной копией в текущем домене приложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...