videos ventajas usar tipos tipo runtimebinderexception runtimebinder puede programacion microsoft los invocar how hashtags funcionan funcion eventos delegados delegado csharp concepto como c# delegates appdomain

c# - ventajas - Pasa y ejecuta el delegado en el dominio de aplicación separado



tipos de delegates (4)

Aunque puede hacer una llamada a un delegado que será manejado por un AppDomain separado, personalmente siempre he usado el método ''CreateInstanceAndUnwrap'' que crea un objeto en el dominio de la aplicación extranjera y le devuelve un proxy.

Para que esto funcione, su objeto tiene que heredar de MarshalByRefObject .

Aquí hay un ejemplo:

public interface IRuntime { bool Run(RuntimesetupInfo setupInfo); } // The runtime class derives from MarshalByRefObject, so that a proxy can be returned // across an AppDomain boundary. public class Runtime : MarshalByRefObject, IRuntime { public bool Run(RuntimeSetupInfo setupInfo) { // your code here } } // Sample code follows here to create the appdomain, set startup params // for the appdomain, create an object in it, and execute a method try { // Construct and initialize settings for a second AppDomain. AppDomainSetup domainSetup = new AppDomainSetup() { ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase, ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName, LoaderOptimization = LoaderOptimization.MultiDomainHost }; // Create the child AppDomain used for the service tool at runtime. childDomain = AppDomain.CreateDomain( "Your Child AppDomain", null, domainSetup); // Create an instance of the runtime in the second AppDomain. // A proxy to the object is returned. IRuntime runtime = (IRuntime)childDomain.CreateInstanceAndUnwrap( typeof(Runtime).Assembly.FullName, typeof(Runtime).FullName); // start the runtime. call will marshal into the child runtime appdomain return runtime.Run(setupInfo); } finally { // runtime has exited, finish off by unloading the runtime appdomain if(childDomain != null) AppDomain.Unload(childDomain); }

En el ejemplo anterior, está codificado para ejecutar un método ''Ejecutar'' pasando información de configuración, y la finalización del método Ejecutar se determina para indicar que todo el código en el dominio de aplicación secundario se ha ejecutado, por lo que tenemos un bloque final que garantiza El dominio de aplicación se descarga.

A menudo, es posible que desee tener cuidado con los tipos que coloca en los ensamblajes; puede usar una interfaz y colocarlos en un ensamblaje separado que tanto la persona que llama (nuestro código que configura el dominio de aplicación como la llama) y la El implementador (la clase Runtime) depende de. Este IIRC permite que el dominio de aplicación principal cargue solo el conjunto que contiene la interfaz, mientras que el dominio de aplicación secundario cargará tanto el conjunto que contiene Runtime como su dependencia (el conjunto IRuntime). Cualquier tipo definido por el usuario que sea utilizado por la interfaz IRuntime (por ejemplo, nuestra clase RuntimeSetupInfo) generalmente también debe ubicarse en el mismo ensamblaje que IRuntime. Además, tenga cuidado de cómo defina estos tipos definidos por el usuario: si son objetos de transferencia de datos (como probablemente sea RuntimeSetupInfo), probablemente debería marcarlos con el atributo [serializable], de modo que se pase una copia del objeto (serializado desde el dominio principal del hijo). Desea evitar que las llamadas se realicen desde un dominio de aplicación a otro, ya que esto es bastante lento. Pasar los DTO por valor (serialización) significa que acceder a los valores en el DTO no implica una llamada entre apartamentos (ya que el dominio de aplicación secundario tiene su propia copia del original). Por supuesto, esto también significa que los cambios de valor no se reflejan en el DTO original del dominio principal del padre.

Como está codificado en el ejemplo, el dominio de aplicación principal terminará cargando los ensamblados IRuntime y Runtime, pero eso se debe a que en la llamada a CreateInstanceAndUnwrap estoy usando typeof (Runtime) para obtener el nombre del ensamblado y el nombre de tipo completo. En su lugar, podría codificar o recuperar estas cadenas de un archivo, lo que desacoplaría la dependencia.

También hay un método en AppDomain llamado ''DoCallBack'' que parece que permite llamar a un delegado en un AppDomain extranjero. Sin embargo, el tipo de delegado que toma es de tipo ''CrossAppDomainDelegate''. La definición de la que es:

public delegate void CrossAppDomainDelegate()

Por lo tanto, no le permitirá pasar ningún dato. Y, como nunca lo he usado, no puedo decirte si hay algún error en particular.

Además, recomiendo buscar en la propiedad LoaderOptimization . Al establecer esto, puede tener un efecto significativo en el rendimiento, ya que algunas configuraciones de esta propiedad obligan al nuevo dominio de aplicación a cargar copias separadas de todos los ensamblajes (y JIT, etc.) incluso si (IIRC) el ensamblaje está en el GAC ( es decir, esto incluye ensamblajes CLR). Esto le puede dar un desempeño horrible si usa una gran cantidad de ensamblajes desde el dominio de aplicaciones de su hijo. Por ejemplo, he usado WPF desde appdomains secundarios, lo que causó enormes retrasos en el inicio de mi aplicación hasta que configuré una política de carga más adecuada.

Quiero ejecutar un fragmento de código en el dominio de aplicación separado con delegado. ¿Cómo puedo hacer esto?

UPD1 : algunos detalles más sobre mi problema Mi programa está procesando algunos datos (una iteración es: obtener algunos datos de DB, evaluarlos y crear ensamblajes en tiempo de ejecución, ejecutar ensamblajes dinámicos y escribir resultados en DB).

Solución actual: cada iteración se ejecuta en un hilo separado. Mejor solución: cada iteración se ejecuta en el dominio de aplicación separado (para descargar conjuntos dinámicos).

UPD2 : Todos, gracias por las respuestas.

He encontrado uno para mí en este hilo: Reemplazo de procesos. Comience con AppDomains


Esto no responde su pregunta directamente, pero quizás sería mejor crear un servicio WCF o un servicio web en el otro Dominio de aplicación para preservar el aislamiento. No conozco su situación particular, pero el diseño arquitectónico aislado es casi siempre el camino correcto.


Necesita leer en .NET Remoting y específicamente en objetos remotos ya que estos son todo lo que puede pasar a través de AppDomains.

El largo y corto de esto es que su objeto se pasa por valor o por referencia (a través de un proxy).

Por valor requiere que su objeto sea serializable. Los delegados no son serializables. Eso significa que esta no es una buena ruta a seguir.

Por referencia, se requiere que herede de MarshalByRefObject . De esta manera, la infraestructura remota puede crear el proxy. Sin embargo, también significa que su delegado se ejecutará en la máquina que lo crea, no en el dominio de la aplicación cliente.

Con todo, va a ser complicado. Es posible que desee considerar la posibilidad de hacer que sus delegados sean objetos serializables completos para que puedan moverse fácilmente de forma remota (y funcionarán bien con otras tecnologías).