Club.NET Almería

Plataforma .NET de Ingenieros/Ingenieros Técnicos en Informática de Almería
¡Bienvenid@ a Club.NET Almería! Iniciar sesión | ÚNETE a la web | Ayuda
en Buscar
Principal Blogs Foros Imágenes Descargas

Incrustación de Aplicaciones con System.AppDomain

Último artículo 06-11-2008, 4:49 escrito por amarquez. 2 respuestas.
Ordenar mensajes: Anterior Siguiente
  •  06-10-2008, 2:32 2468

    Incrustación de Aplicaciones con System.AppDomain

    Con C#, y gracias a System.AppDomain extender la funcionalidad de una aplicación mediante plugins es un juego de niños. Una forma un tanto bruta de hacerlo, es considerar que los plugins son programas externos que ejecutan una serie de acciones necesarias y pueden devolver un valor (en forma de archivo en disco). Un ejemplo de este tipo de plugins lo tenemos en la implementación de los plugins para el programa de edición gráfica GIMP (GNU Image Manipulation Program), el cual se vale de multitud de pequeños plugins en forma de programas ejecutables que se utilizan para aplicar filtros o efectos a una imagen.

    En este caso, vamos a hacer un programa muy sencillo que funcione como un servidor de aplicaciones, de forma que dos o más aplicaciones se puedan lanzar simultáneamente en diferentes hilos, lo que permite aprovechar los procesadores multicore ejecutando cada aplicación en cores distintos.

    Forma de uso del ejemplo: Se crean dos proyectos de consola, se copia el código fuente del servidor en uno, y el del programa ejemplo en otro. Una vez creados se generan los dos, y se copian a la carpeta raíz ( C:\ ), y se ejecuta el programa servidor. Éste incrustará dos copias del programa ejemplo, que imprime cierto número de veces su identificador de ejecución único, y se podrá observar cómo los resultados impresos por cada programa se van intercalando gracias al paralelismo de usar hilos.

    Para los más perezosos, incluyo como adjunto al artículo un zip con los proyectos y el código fuente que he utilizado (nota: el formato de los archivos de proyecto es de Visual Studio 2008, aunque el código fuente en sí funciona perfectamente con Visual Studio 2005!!)

    Servidor (programa que incrusta otros programas en hilos):

    using System;  
    using System.Threading;  
    //using System.Reflection;  
    namespace remoteInvoker  
    {  
      class Program  
      {  
        static void Main(string[] args)  
        {  
          //Mostrar el AppDomain predefinido.  
          string callingDomainName = Thread.GetDomain().FriendlyName;  
          Console.WriteLine(”AppDomain Servidor: “+callingDomainName);  
          //Invoca al creador de aplicaciones  
          crearAplicacion(@”c:\appdomainExperiment.exe”);  
          crearAplicacion(@”c:\appdomainExperiment.exe”);  
          //Fin  
          Console.WriteLine(”Server: exit”);  
          Console.ReadKey(true);  
        }  
      
        /// Crea un hilo que ejecuta una aplicación  
        private static void crearAplicacion(string aplicacion) {  
          Aplicacion app = new Aplicacion(aplicacion);  
        }  
      }  
      
      /// Incrusta un ensamblado en un hilo para ejecutarlo  
      class Aplicacion {  
        // Nombre (url) de la aplicación  
        string appName;  
      
        /// Constructor, crea un dominio predeterminado  
        public Aplicacion(string aplicacion) {  
          appName = aplicacion;  
          Thread appThread = new Thread(new ThreadStart(doWork));  
          appThread.Start();  
        }  
      
        /// Método de ejecución del hilo  
        private void doWork(){  
          //Crea un dominio de ejecución para este hilo  
          AppDomain dominio = AppDomain.CreateDomain(”serverDomain”);  
          //Ejecuta el ensamblado  
          dominio.ExecuteAssembly(appName);  
          //Descarga el Dominio  
          AppDomain.Unload(dominio);  
        }  
      }  
    }  

    Programa de Ejemplo:

    using System;  
    using System.Threading;  
    namespace appdomainExperiment  
    {  
      class Program  
      {  
      static void Main()  
      {  
        System.Console.BackgroundColor = ConsoleColor.Blue;  
        Console.WriteLine(”Hola Mundo! (Método Principal)”);  
      
        //Obtiene el identificador único de ensamblado en ejecución  
        Guid k = System.Guid.NewGuid();  
        for (int i = 0; i < 10; i++)  
        {  
          Console.WriteLine(k.ToString());  
          Thread.Sleep(10);  
        }  
        try  
        {  
          //Escribe el nombre de dominio de la aplicación  
          Console.WriteLine(”AppDomain Cliente: ” +  
          System.AppDomain.CurrentDomain.DomainManager.EntryAssembly.FullName);  
        }  
        catch  
        {  
          Console.WriteLine(”AppDomain Cliente: Aplicación independiente”);  
        }  
        System.Console.BackgroundColor = ConsoleColor.Black;  
        }  
      }  



    Fullbyte Alchemist
  •  06-11-2008, 3:43 2473 en respuesta a 2468

    Re: Incrustación de Aplicaciones con System.AppDomain

    Y si dos de las aplicaciones que este servidor gestiona usan clases llamadas igual, pero diferentes, ¿como se gestiona la colision?

    José Antonio Álvarez Bermejo.
    - - - disclaimer - - -
    Las opiniones son como el olor corporal, a cada uno le gusta el suyo. No te esfuerces en oponerte a mi opinión por que esa es tú opinión y a mi me trae sin cuidado.
  •  06-11-2008, 4:49 2477 en respuesta a 2473

    Re: Incrustación de Aplicaciones con System.AppDomain

    Si te fijas en el ejemplo, al cargar las aplicaciones en vez de poner un mensaje distintivo "soy aplicación uno" y "soy aplicación 2", con dos programas distintos, el programa de prueba lo que hace es obtener el identificador de ensamblado, de forma que aunque tengan igual nombre (de hecho, aunque sean la misma clase/aplicación) los identificadores son distintos.

    Los programas del ejemplo son lo más sencillos posible (que usen hilos), así que lo que se hace es cargar un ensamblado y ejecutarlo, esto significa que se busca el punto de entrada de ejecución (método estático main) e iniciar la ejecución de ese método. Aproximaciones más elegantes requieren la disponibilidad de diferentes clases y métodos. Para ello, lo que se debe hacer es crear una interfaz de aplicación con una serie de métodos comunes. 

    Algunos métodos útiles que se deberían incluir en la interfaz en este caso son:

    • Un método de inicialización, para poder incluir la información necesaria para el cómputo (un List<object> por ejemplo, es lo suficientemente genérico como para poder pasar casi todo tipo de datos, y que se el proceso de inicialización se encargue de interpretarlos)
    • Un método indicador de progreso, que permita determinar cuánto queda para que la operación se complete.
    • Un método indicador de estado, para saber qué se está haciendo en cada instante.
    • Uno o varios métodos de ejecución, responsables de realizar las operaciones solicitadas y ofrecer funcionalidad al programa que carga la clase.
    • Métodos de cancelación/pausa pueden ser de utilidad.
    • Métodos de acceso a los resultados generados.

    Así, podemos implementar cualquier clase que deseemos, como una dll para procesar imágenes, una dll para comprimir sonido o una dll para realizar cálculos científicos, y en caso de que se desee poder utilizarla como plugin "cargable", simplemente implementando la interfaz definida por el "gestor de plugins" se podrá incrustar y utilizar en la aplicación.

    Tal vez en algún momento me decida a hacer un "cargador genérico de plugins", aunque de momento me conformo con la gestión de dependencias de Visual Studio para las dll que utilizo.


    Fullbyte Alchemist
Ver como una fuente de noticias RSS en XML
Ofrecido por Community Server (Personal Edition)