c# remoting appdomain

c# - Utilice el atributo[Serializable] o subclases de MarshalByRefObject?



remoting appdomain (4)

Me gustaría usar un objeto en AppDomains.

Para esto puedo usar el atributo [Serializeable]:

[Serializable] class MyClass { public string GetSomeString() { return "someString" } }

O subclase de MarshalByRefObject:

class MyClass: MarshalByRefObject { public string GetSomeString() { return "someString" } }

En ambos casos puedo usar la clase así:

AppDomain appDomain = AppDomain.CreateDomain("AppDomain"); MyClass myObject = (MyClass)appDomain.CreateInstanceAndUnwrap( typeof(MyClass).Assembly.FullName, typeof(MyClass).FullName); Console.WriteLine(myObject.GetSomeString());

¿Por qué ambos enfoques parecen tener el mismo efecto? ¿Cuál es la diferencia en ambos enfoques? ¿Cuándo debo favorecer el enfoque uno sobre el otro?

EDIT: En la superficie, sé que hay diferencias entre ambos mecanismos, pero si alguien saltó de un arbusto y me hizo la pregunta, no pude darle una respuesta adecuada. Las preguntas son preguntas bastante abiertas. Esperaba que alguien pudiera explicarlo mejor de lo que yo podía hacer.


¿Por qué ambos enfoques tienen el mismo efecto?

No tienen el mismo efecto.

Con MarshalByRefObject usted hace referencia a un objeto a través de los límites del dominio de aplicación. Con [Serializable] se está haciendo una copia del objeto. Esto se mostrará si el estado del objeto se modifica en el dominio secundario y luego se examina nuevamente (o ejecute Console.WriteLine dentro del dominio de aplicación secundario).


El uso de MarshallByRef ejecutará sus métodos en el dominio de aplicación remoto. Cuando utiliza CreateInstanceAndUnwrap con un objeto Serializable, se realiza una copia del objeto en el dominio de aplicación local, por lo que cualquier llamada de método se ejecutará en el dominio de aplicación local.

Si lo que desea es comunicarse entre AppDomains, vaya con el enfoque MarshallByRef.

Un ejemplo:

using System; using System.Reflection; [Serializable] public class SerializableClass { public string WhatIsMyAppDomain() { return AppDomain.CurrentDomain.FriendlyName; } } public class MarshallByRefClass : MarshalByRefObject { public string WhatIsMyAppDomain() { return AppDomain.CurrentDomain.FriendlyName; } } class Test { static void Main(string[] args) { AppDomain ad = AppDomain.CreateDomain("OtherAppDomain"); MarshallByRefClass marshall = (MarshallByRefClass)ad.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "MarshallByRefClass"); SerializableClass serializable = (SerializableClass)ad.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "SerializableClass"); Console.WriteLine(marshall.WhatIsMyAppDomain()); Console.WriteLine(serializable.WhatIsMyAppDomain()); } }

Este código mostrará "OtherAppDomain" cuando llame a WhatIsMyAppDomain desde el objeto MarshallByRef, y su nombre de dominio de aplicación predeterminado cuando llame desde el objeto Serializable.


Estos enfoques tienen efectos dramáticamente diferentes.

Con la versión MarshalByRef está creando 1 instancia de su objeto. Vivirá en el recién creado AppDomain. Todo el acceso al objeto se realiza a través de un TransparentProxy .

Con la versión Serializable se crean 2 instancias de su objeto. Uno se crea en el dominio de aplicación recién creado. La llamada CreateInstanceAndUnwrap luego serializará este objeto y lo deserializará en el dominio de aplicación original. Esto crea una segunda versión del objeto que es completamente independiente de la primera. De hecho, el próximo GC casi seguramente eliminará el objeto original y quedará con una instancia.


MarshalByRefValue y Serializable implementan diferentes semánticas para la comunicación remota / cruzada de AppDomain. MarshalByRefValue esencialmente le brinda semántica de referencia a través de un objeto proxy, mientras que Serializable le brinda semántica de valor (es decir, el estado del objeto se copia).

En otras palabras, MarshalByRefValue le permitirá modificar la instancia en diferentes dominios de aplicación, mientras que Serializable no lo hará. El último es útil cuando solo necesita obtener la información de un dominio de aplicación a otro, por ejemplo, para obtener el contenido de una excepción de un dominio de aplicación a otro.