2010-10-18 25 views
12

Comenzaré diciendo que no soy un desarrollador de .NET, pero me han lanzado a un proyecto en el que necesito usar MSMQ para una aplicación web ASP clásica puede enviar mensajes a un servicio de Windows C# que maneja el procesamiento. Tengo experiencia en la integración de otras colas de mensajes con otros idiomas, pero como mencioné, no tengo mucha experiencia con el desarrollo de .NET y Windows, por lo que sería muy útil recibir alguna orientación.Cómo crear un servicio de escucha C# para MSMQ como un servicio de Windows

Aquí están mis preguntas ...

  1. Podría alguien proporcionar algo de código C# básica que escucha a una cola MSMQ existente y responde al nuevo mensaje al hacer algo tan simple como escribir la fecha y hora actual en un registro archivo o enviar un correo electrónico?

  2. ¿Cómo empaqueté este código en Visual Studio .NET para crear e instalar un servicio de Windows? (¿Qué tipo de proyecto debería ser, etc. Estoy usando Visual C# 2010 Express.)

  3. Finalmente, no estoy seguro de qué versión y/o implementación de MSMQ debo usar para mis requisitos con ASP clásico. Creo que la versión COM es lo que necesito, pero también he leído acerca de una nueva versión de WCF, así como las diferencias entre 3.0 y 4.0. ¿Podría alguien darme una indicación sobre la versión que debería usar?

¡Muchas gracias!

Respuesta

3

Por lo que sé, Visual Studio Express no tiene una plantilla de proyecto para un servicio. Eso no significa que no pueda escribir un servicio de Windows con VSE, solo que no tendrá una plantilla para comenzar.

Para crear un servicio, simplemente puede crear una aplicación de consola normal. Cree la clase de servicio que será responsable de la implementación del servicio real. Se verá algo como esto

using System.ServiceProcess; 

namespace WindowsService1 
{ 
    public partial class Service1 : ServiceBase 
    { 
    public Service1() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
    } 

    protected override void OnStop() 
    { 
    } 
    } 
} 

continuación, el código de inicio del servicio puede entrar en la función Main de su servicio.

using System.ServiceProcess; 

namespace WindowsService1 
{ 
    static class Program 
    { 
    static void Main() 
    { 
     ServiceBase[] ServicesToRun; 
     ServicesToRun = new ServiceBase[] 
      { 
       new Service1() 
      }; 
     ServiceBase.Run(ServicesToRun); 
    } 
    } 
} 

Eso debería darle el marco básico para su servicio. La otra cosa que necesitará es agregar un instalador para el servicio para que pueda instalarse como un servicio. Lo siguiente debería ayudarlo a comenzar, tenga en cuenta que he probado esto en la nota.

using System.ComponentModel; 
using System.Configuration.Install; 
using System.ServiceProcess; 

namespace WindowsService1 
{ 
    [RunInstaller(true)] 
    public class ProjectInstaller : Installer 
    { 
    private ServiceProcessInstaller serviceProcessInstaller1; 
    private ServiceInstaller serviceInstaller1; 

    public ProjectInstaller() 
    { 
     this.serviceProcessInstaller1 = new ServiceProcessInstaller(); 
     this.serviceInstaller1 = new ServiceInstaller(); 

     this.serviceProcessInstaller1.Password = null; 
     this.serviceProcessInstaller1.Username = null; 

     this.serviceInstaller1.ServiceName = "Service1"; 

     this.Installers.AddRange(new System.Configuration.Install.Installer[] { 
     this.serviceProcessInstaller1, 
     this.serviceInstaller1}); 
    } 
    } 
} 

Dado lo anterior, debe tener suficiente para buscar o solicitar más detalles sobre la creación del servicio. En cuanto a la escucha de MSMQ, puede utilizar el siguiente artículo de MSDN como punto de partida

http://msdn.microsoft.com/en-us/library/ms978425.aspx

+0

excelente código de muestra para comenzar a usar el servicio de Windows, gracias. – philfeyn

+0

¿hay otras formas de instalar el servicio, incluso si es una instalación manual? Tener que codificar el nombre de usuario y la contraseña para ejecutar el servicio en el código me parece una mala práctica. – philfeyn

+0

@philfeyn, puede configurar ServiceProcessInstaller.Account para seleccionar el tipo de cuenta. Si está configurado en ServiceAccount.User y el nombre de usuario/contraseña están establecidos en null, se le solicitarán las credenciales cuando instale el servicio. Puede instalar manualmente el servicio utilizando InstallUtil.exe que viene con .NET framework. –

8

Puede esperar a que un mensaje en una cola dada usando el siguiente código (Usted desea utilizar la cola privada llamada SomeQueue en su ordenador, llamado ComputerName => NombreCola = @ "equipo \ private $ \ SomeQueue")

public void AsyncWatchQueue(object encapsulatedQueueName) 
    { 
     Message newMessage; 
     MessageQueue queue; 

     string queueName = encapsulatedQueueName as string; 
     if (queueName == null) 
      return; 

     try 
     { 
      if (!MessageQueue.Exists(queueName)) 
       MessageQueue.Create(queueName); 
      else 
      { 
       queue = new MessageQueue(queueName); 

       if (queue.CanRead) 
        newMessage = queue.Receive(); 
      } 
      HandleNewMessage(newMessage); // Do something with the message 
     } 
     // This exception is raised when the Abort method 
     // (in the thread's instance) is called 
     catch (ThreadAbortException e) 
     { 
      //Do thread shutdown 
     } 
     finally 
     { 
      queue.Dispose(); 
     } 
    } 

Nota: el método Receove bloqueará hasta el mensaje se recibe un momento en el que va a eliminar el mensaje de la cola y devolverlo.

edición: código añadido para la ejecución de la parte multiproceso (y renombró el método anterior firma)

Tema código de creación:

 public Thread AddWatchingThread(string QueueName) 
    { 
     Thread Watcher = 
      new Thread(new ParameterizedThreadStart(AsyncWatchQueue)); 
     Watcher.Start(QueueName); 
     // The thread instance is used to manipulate (or shutdown the thread) 
     return Watcher; 
    } 

Voy a señalar, que esta no se ha probado bacalao, es solo un ejemplo rápido

+0

¿Seguro que la llamada Exists() funcionará? http://blog.plumbersmate.eu/archive/2010/10/18/checking-if-msmq-queues-exist-is-hard-work-so-should.aspx –

+0

@Neowizard, utilizando el código de ejemplo del servicio de Windows anterior , ¿su código pertenece al método OnStart() de WindowsService1 correcto? Cuando x.Receive() recibe un mensaje, ¿dónde se devuelve? ¿Puedes proporcionar algún código para un ejemplo de tu último comentario sobre la creación de un nuevo hilo que espere mensajes? Por ejemplo, cuando se recibe un nuevo mensaje? ¡Gracias! – philfeyn

+0

El código anterior es solo un código básico para configurar un hilo para esperar a que llegue un mensaje en la cola. No tiene en cuenta los problemas resultantes de los servicios o cualquier otra cosa que no sea el MSMQ. Agregaré un código a la respuesta para mejorarlo, pero será una mejor idea que hagas algo de sandbox jugando con la clase de MessageQueue \ object – Neowizard

Cuestiones relacionadas