Статические переменные и AppDomains, что происходит?
У меня
public static class A
{
public static string ConnString;
}
[Serializable]
public class Test{
// Accesing A 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"
предполагается изменить строку во вновь создаваемом домене, но, похоже, оба они ссылаются на один и тот же экземпляр!
Почему, что здесь происходит?
Ответы
Ответ 1
Существует только два способа доступа класса из другого AppDomain: один из них - это класс [Serializable]
, как ваш тестовый класс, другой - если класс наследуется от MarshalByRefObject. Поскольку ваш класс является Serializable, его копия создается для каждого вызова Cross-AppDomain. Итак, Test
, что главный appdomain получает, когда вы вызываете...
Test TObj = newDomain.CreateInstanceAndUnwrap(typeof(Test).Assembly.FullName, typeof(Test).FullName) as Test;
на самом деле не экземпляр Test, который был создан в DomNew AppDomain, это копия, локальная для "основного" AppDomain, и поэтому ссылается на статические переменные из "основного" AppDomain.
Если вы хотите, чтобы Test
отображал поведение, которое вы ожидаете, сделайте его наследуемым от MarshalByRefObject вместо Serializable.
Ответ 2
Вы отметили свой тестовый класс как Serializable. Это не верно. Вы должны были получить от MarshalByRef. В противном случае TObj будет просто локальной копией в текущем AppDomain.