2012-03-21 13 views
21

tengoInstancias de variables estáticas y AppDomains, ¿qué está pasando?

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" 
} 

pero no! ¡Las dos líneas de escritura, imprimen el mismo valor "NewDomainString"! ¿POR QUÉ ???

este código

TObj.ConnString = "NewDomainString" 

se supone que cambiar la cadena en el dominio de nueva creación, pero parece que ambos se refieren a la misma instancia!

¿Qué está pasando aquí?

+6

Posible duplicado de http://stackoverflow.com/questions/4298913/static-fields-in-appdomain – daryal

+2

No marque sus títulos con "C#" y tal. Para eso son las etiquetas. –

+0

¡Tienes razón, John! Novato aquí :) ¡Estoy aprendiendo! ¡Gracias! –

Respuesta

21

Solo hay dos maneras para que una clase sea accesible desde otro AppDomain: una es la clase es [Serializable], como su clase de prueba, la otra es si la clase hereda de MarshalByRefObject. Debido a que su clase es Serializable, se crea una copia para cada llamada de AppDomain. Por lo que el Test que el dominio de aplicación principal recibe cuando se llama ...

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

realidad no es la instancia de prueba que se creó en el "DomNew" AppDomain- se trata de una copia local para el dominio de aplicación "principal", y por lo tanto, hace referencia a las variables estáticas del AppDomain "principal".

Si desea que Test muestre el comportamiento que espera, hágalo heredar de MarshalByRefObject en lugar de Serializable.

+1

Nit: en realidad hay una tercera vía. mariscal por sangrado http://www.bluebytesoftware.com/blog/PermaLink,guid,884ca8af-76fb-4753-a9d9-d12075dabb51.aspx – JaredPar

+0

@JaredPar yikes, sí ... me hace dar un respingo. –

+0

Gracias, eso era realmente lo que estaba buscando. Sucedió que encontré la respuesta por mi cuenta poco después de hacer la pregunta. Por alguna razón, no probé la herencia de MarshalByRef, aunque sabía que existía tal cosa. Creo que fui engañado por una respuesta en otro foro que decía que estas dos formas (Serializable Attribute y MarshalByRef inheritance) eran idénticas. Sin embargo, creo que si Serializable Attirbute es una forma de hacer una copia "local" de la clase, en realidad no accede al objeto desde otro dominio, ¿verdad? ¿Es solo para "leer" el estado de un objeto de otro dominio? –

12

Marcó su clase de prueba como Serializable. Esto está mal. Deberías haber derivado de MarshalByRef. De lo contrario, TObj solo será una copia local en el dominio de la aplicación actual.

+0

Así es :) ¡Gracias, amigo! –

Cuestiones relacionadas