Creación de una interfaz de usuario para monitorear e interactuar con un servicio de Windows en ejecución

Necesito ejecutar un montón de procesos conectables en un servicio de Windows en mi servidor y quiero crear una interfaz de usuario que me permita interactuar con cada uno de los complementos en uso por el servicio.

¿Cuál es el método (o métodos) más común para la comunicación entre una interfaz de usuario y un servicio de Windows de larga duración? Estoy pensando en proporcionar una ubicación intermedia como una base de datos y usar algún tipo de cola de mensajería para emitir comandos al servicio. ¿Alguno de ustedes ha implementado tal enfoque, o algún otro enfoque superior? ¿Qué problemas has encontrado en el proceso?

¡No uses el control remoto! Aunque ciertamente funcionará, Microsoft dice que la comunicación remota es una tecnología heredada y que todas las nuevas aplicaciones distribuidas deben desarrollarse utilizando WCF. Vea aquí para más detalles.

Windows Communication Foundation (WCF) es la forma recomendada para que dos procesos .NET se comuniquen entre sí. WCF proporciona un modelo de progtwigción unificado que simplifica enormemente el desarrollo distribuido al abstraer muchas de las complejidades asociadas con mecanismos de comunicación específicos, por ejemplo, sockets, tuberías, etc.

Dados los detalles de su situación, sugeriría que cada complemento de servicio de Windows sea un servicio WCF. Para cada servicio WCF, es decir, un complemento, defina la interfaz que necesita exponer a su interfaz de usuario. La interfaz es simplemente una interfaz C # adornada con el atributo ServiceContract . Esta interfaz contiene los métodos, cada uno de los cuales está adornado con el atributo OperationContract , que su interfaz de usuario utilizará para comunicarse con el servicio WCF (complemento). Estos métodos pueden aceptar y devolver cualquier tipo de .NET serializable o, como suele ser el caso, sus propios tipos personalizados. Para usar tipos personalizados con WCF, simplemente decórelos con el atributo DataContract y marque los miembros que desea intercambiar a través de WCF con el atributo DataMember .

Una vez que haya definido su interfaz ServiceContract , defina una clase que implemente esa interfaz. Cada método OperationContract hace lo que necesita hacer, por ejemplo, interactuar con la base de datos, calcular algún valor, etc. Una vez que haya hecho esto, habrá definido efectivamente un servicio WCF. Aquí hay un breve ejemplo, pero trabajando:

using System.ServiceModel; namespace AdditionServiceNamespace { [DataContract] public class Complex { [DataMember] public int real; [DataMember] public int imag; } [ServiceContract] public interface IAdditionService { [OperationContract] Complex Add(Complex c1, Complex c2); } public class AdditionService : IAdditionService { public Complex Add(Complex c1, Complex c2) { Complex result = new Complex(); result.real = c1.real + c2.real; result.imag = c1.imag + c2.imag; return result; } } } 

El siguiente paso es alojar este servicio WCF para que esté disponible para que lo use su interfaz de usuario. Dado que utilizará un servicio de Windows, el hospedaje de su servicio WCF se realiza con la suficiente facilidad en la callback OnStart() de su servicio de Windows, por lo que:

 using System.ServiceModel; using System.ServiceProcess; using AdditionServiceNamespace; namespace WindowsServiceNamespace { public class WindowsService : ServiceBase { static void Main() { ServiceBase[] ServicesToRun = new ServiceBase[] { new WindowsService() }; ServiceBase.Run(ServicesToRun); } private ServiceHost _host; public WindowsService() { InitializeComponent(); } protected override void OnStart(string[] args) { _host = new ServiceHost(typeof(AdditionService)); _host.Open(); } protected override void OnStop() { try { if (_host.State != CommunicationState.Closed) { _host.Close(); } } catch { // handle exception somehow...log to event viewer, for example } } } } 

Lo único que queda por hacer es definir un archivo app.config para su servicio de Windows que configure ciertos aspectos requeridos de su servicio WCF. Esto puede parecer una exageración, pero tenga en cuenta dos cosas. En primer lugar, Visual Studio le brinda un archivo app.config básico automáticamente cuando agrega una clase de servicio WCF a su proyecto. En segundo lugar, el archivo app.config le da una gran cantidad de control sobre su servicio WCF sin requerir cambios en el código. Aquí está el archivo app.config complementario para el ejemplo anterior:

             

No se requieren cambios de código! Realice el cambio, reinicie su servicio y su servicio WCF ahora está disponible para máquinas remotas. Incluso puede permitir múltiples puntos finales para el mismo servicio WCF si así lo desea. El punto es que el archivo app.config ofrece una tremenda flexibilidad sin requerir cambios en el código.

¡Eso es! Ahora tiene un servicio WCF alojado dentro de su servicio de Windows disponible para que lo use su interfaz de usuario.

Entonces, ¿cómo funciona el lado UI, es decir, el lado del cliente?

Aquí es donde el poder real de WCF entra en juego. Al comenzar con WCF, lo más fácil es aprovechar las capacidades de generación de código de Visual Studio. Asegúrese de que se esté ejecutando su servicio de Windows (el que aloja el servicio Addition). En su proyecto de interfaz de usuario, haga clic con el botón derecho en su proyecto en el Explorador de soluciones y seleccione la opción de menú Agregar referencia de servicio … En el cuadro Dirección , escriba net.pipe://localhost/AdditionService y haga clic en el botón Ir . Debería ver el servicio AdditionService en la lista de Servicios . En el cuadro Espacio de nombres , escriba AdditionService y haga clic en el botón Aceptar .

La realización de estos pasos generará un proxy de cliente y un archivo app.config correctamente definido que se agregarán a su proyecto de IU. Este proxy de cliente se convierte en su API AdditionService del lado del cliente, y usted lo usa así:

 using TestConsoleApp.AdditionService; namespace TestConsoleApp class Program { static void Main(string[] args) { AdditionServiceClient client = new AdditionServiceClient(); Complex c1 = new Complex(), c2 = new Complex(); c1.real = 3; c1.imag = 5; c2.real = 1; c2.imag = 7; Complex result = client.Add(c1, c2); } } } 

Note lo simple que es esto. Básicamente, se crea una instancia de un proxy de cliente, AdditionServiceClient . Entonces se crean dos objetos Complex . Finalmente, se invoca el método Add() en el proxy del cliente y se devuelve un resultado Complex .

Lo que está sucediendo detrás de escena es que el método Add() del proxy del cliente en realidad pasa los dos objetos Complex al servicio WCF de AdditionService alojado en el servicio de Windows. El AdditionService realiza la adición y luego devuelve el resultado. Todo esto sucede sobre una tubería con nombre, ¡pero observe que aquí no hay ningún código específico de tubería con nombre! WCF ha abstraído toda esa complejidad detrás de un modelo de progtwigción definido por la interfaz IAdditionService.

Sé que esto es mucha información para digerir, pero espero que sea evidente cuán poderoso y fácil de usar puede ser WCF. Por supuesto, este ejemplo solo afecta a un pequeño subconjunto de todo lo que está disponible dentro de WCF.

Sin embargo, al final, WCF debe ser el mecanismo que utilice para comunicarse entre su interfaz de usuario y su servicio de Windows. Para obtener más información, recomendaría encarecidamente el libro de Juval Lowy Progtwigción de servicios WCF para todo lo relacionado con WCF. También puede visitar su sitio web, IDesign.net , para obtener muestras gratuitas de códigos WCF. Para más información sobre WCF, vea este video gratuito en dnrTV. Cubre el propósito de WCF y demuestra la progtwigción de WCF a través de algunos ejemplos fáciles de seguir.

Su mejor apuesta es usar .NET a distancia sobre un canal IPC.

Aunque parece complicado de instalar, es bastante fácil la segunda vez.

Le sugiero que juegue con algunas muestras primero al exponer objetos remotos de una aplicación a otra.

No he usado colas de mensajes antes, así que no puedo comentar sobre eso.