Compartir a través de


Uso de Visual C# para escribir y leer desde Microsoft Message Queuing

En este artículo se describe cómo escribir y leer desde Microsoft Message Queuing (MSMQ) en Visual C#.

Versión original del producto: Microsoft Message Queuing
Número de KB original: 815811

En esta tarea

Resumen

En este artículo se describe lo siguiente:

  • Cómo crear un mensaje y enviarlo a MSMQ en una aplicación de Windows.
  • Cómo leer de una cola privada y deserializar el contenido del mensaje para su visualización.

Requisitos

Los siguientes elementos describen el hardware, el software, la infraestructura de red, las aptitudes y los conocimientos recomendados y los service packs necesarios:

  • Uno de los siguientes sistemas operativos con MSMQ instalado (se incluye como opción en los cuatro sistemas operativos): Windows 2000 Professional (o Server) o Windows XP Professional (o Server).

En este artículo también se supone que está familiarizado con lo siguiente:

  • MSMQ
  • Uso de herramientas desde el símbolo del sistema

volver a la parte superior

Escribir en y leer desde MSMQ

El System.Messaging espacio de nombres en .NET Framework contiene las clases necesarias para leer y escribir en MSMQ. Para crear una pequeña aplicación de Windows que imita un sistema de pago de facturas en línea, siga estos pasos:

  1. Abra Visual Studio .NET o Visual Studio 2005.

  2. Cree una nueva aplicación de Windows en Visual C#y, a continuación, asígneles el nombre MSMQ.

  3. Para mostrar Explorador de soluciones si no aparece, presione CTRL+ALT+L. En el Explorador de soluciones, haga clic con el botón secundario del mouse en Referencias y, a continuación, haga clic en Agregar referencia.

  4. En la pestaña .NET, seleccione System.Messaging.dll en la lista de archivos .dll. Haga clic en Seleccionar y luego haga clic en Aceptar.

    Nota:

    En Visual Studio 2005, haga clic en el archivo System.Messaging.dll en la lista de archivos DLL y, a continuación, haga clic en Aceptar.

  5. Form1.cs está abierto en la vista Diseño. Si no está abierto, haga doble clic en Form1.cs en Explorador de soluciones.

  6. Presione CTRL+ALT+X para abrir el cuadro de herramientas. En el Cuadro de herramientas, haga clic en la pestaña Formularios Windows Forms .

  7. En el Cuadro de herramientas, arrastre lo siguiente al centro de Form1:

    • Cuatro filas cada una de las etiquetas y un cuadro de texto (situado a la derecha de cada etiqueta).
    • Debajo de las etiquetas y cuadros de texto, arrastre dos controles Button a Form1.
  8. Haga clic con el botón derecho en los controles, haga clic en Propiedades y, a continuación, establezca la propiedad Text para las etiquetas en lo siguiente (en orden):

    • Pagar a:
    • Tu nombre:
    • Amount (Cantidad):
    • Fecha de vencimiento:
  9. En el cuadro de diálogo Propiedades , establezca la propiedad Text de button1 en Enviar pago y establezca la propiedad Text de button2 en Procesar pago.

  10. Esta aplicación funciona con una cola privada que primero debe crear en la consola de administración de equipos. Para ello, siga estos pasos:

    1. En el escritorio, haga clic con el botón derecho en Mi equipo y, a continuación, haga clic en Administrar.
    2. Expanda el nodo Servicios y aplicaciones para buscar MSMQ.

    Nota:

    Si no encuentra MSMQ, no está instalado.

  11. Expanda Message Queuing, haga clic con el botón derecho en Colas Privadas, seleccione Nuevo, a continuación, haga clic en Cola Privada.

  12. En el cuadro Nombre de la cola, escriba billpay, a continuación, haga clic en Aceptar.

    Nota:

    No active la casilla Transaccional . Deje abierta la consola de administración de equipos porque vuelve a ella más adelante para ver los mensajes.

  13. En la parte superior del código de Form1, agregue dos USING instrucciones antes de la declaración de la clase para incluir las clases adicionales que se encuentran en el System.Messaging espacio de nombres y en los System.Text espacios de nombres. (El System.Text espacio de nombres se utiliza para la StringBuilder clase, una nueva clase de .NET Framework que se recomienda su uso al concatenar cadenas).

    using System.Messaging;
    using System.Text;
    
  14. Cree una estructura que contenga variables que contengan los datos que definen un pago. Para crear la estructura, agregue el código siguiente después del procedimiento Main:

    public struct Payment
    {
        public string Payor,Payee;
        public int Amount;
        public string DueDate;
    }
    
  15. Agregue el código siguiendo los pasos siguientes al Click evento de button1.

    1. Establezca las propiedades de la estructura en valores de los elementos de formulario como se indica a continuación:

      Payment myPayment;
      myPayment.Payor = textBox1.Text;
      myPayment.Payee = textBox2.Text;
      myPayment.Amount = Convert.ToInt32(textBox3.Text);
      myPayment.DueDate = textBox4.Text;
      
    2. Cree una instancia de la Message clase y, a continuación, establezca la Body propiedad en la payment estructura :

      System.Messaging.Message msg = new System.Messaging.Message();
      msg.Body=myPayment;
      
    3. Para enviar un mensaje a MSMQ, cree una instancia de clase MessageQueue y llame al método Send que pasa el objeto Message. La MessageQueue clase es el contenedor que administra la interacción con MSMQ.

      Nota:

      Sintaxis para establecer la ruta de acceso de la cola privada que creó en la consola de administración de equipos. Las colas privadas tienen el formato machinename\Private$\queuename. Se hace referencia a las máquinas host locales con un punto o un punto y seguido (se muestra como .).

      MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay");
      msgQ.Send(msg);
      

      El código ahora existe para enviar un mensaje a MSMQ. .NET Framework serializa automáticamente el mensaje mediante un XMLMessageFormatter objeto . Este objeto se crea implícitamente cuando se envían mensajes.

  16. Agregue el código de los siguientes pasos al evento Click de button2. El button2_Click controlador de eventos recibe y procesa el mensaje de pago que se envía en el button1 controlador de eventos.

    1. La primera línea de código es la misma que la línea de código que se encuentra en el primer controlador de eventos:

      MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
      
    2. Cree una matriz de tipos para pasar a la XMLMessageFormatter clase .

      Nota:

      Esta clase debe crearse explícitamente al recibir mensajes. El constructor de la XMLMessageFormatter clase toma una matriz de cadenas de nombres de tipo o, preferiblemente, una Type matriz de tipos:

      Payment myPayment=new Payment();
      Object o=new Object();
      System.Type[] arrTypes=new System.Type [2];
      arrTypes[0] = myPayment.GetType();
      arrTypes[1] = o.GetType();
      msgQ.Formatter = new XmlMessageFormatter(arrTypes);
      myPayment=((Payment)msgQ.Receive().Body);
      

      Estos tipos indican al XMLMessageFormatter cómo deserializar el mensaje.

    3. Los mensajes se reciben llamando al Receive método . Acceda a la Body propiedad para leer el contenido del mensaje. La Body propiedad devuelve un objeto, por lo que el objeto debe ser convertido al tipo de pago para recuperar el contenido en una forma utilizable.

      StringBuilder sb = new StringBuilder();
      sb.Append("Payment paid to: " + myPayment.Payor);
      sb.Append("\n");
      sb.Append("Paid by: " + myPayment.Payee);
      sb.Append("\n");
      sb.Append("Amount: $" + myPayment.Amount.ToString());
      sb.Append("\n");
      sb.Append("Due Date: " + Convert.ToDateTime(myPayment.DueDate));
      
    4. Cree un cuadro de mensaje para mostrar los resultados:

      MessageBox.Show(sb.ToString(), "Message Received!");
      

volver a la parte superior

Lista de código completa (Form1.cs)

using System.Messaging;
using System.Text;
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication1
{
/// <summary>
/// Summary description for Form1.
/// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.TextBox textBox2;
        private System.Windows.Forms.TextBox textBox3;
        private System.Windows.Forms.TextBox textBox4;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;
        public Form1()
        {
        // Required for Windows Form Designer support
            InitializeComponent();
        // TODO: Add any constructor code after InitializeComponent call
        }
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.textBox3 = new System.Windows.Forms.TextBox();
            this.textBox4 = new System.Windows.Forms.TextBox();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // label1
            this.label1.Location = new System.Drawing.Point(8, 24);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(104, 32);
            this.label1.TabIndex = 0;
            this.label1.Text = "Pay To:";
            // label2
            this.label2.Location = new System.Drawing.Point(8, 80);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(104, 32);
            this.label2.TabIndex = 1;
            this.label2.Text = "Your Name:";
            // label3
            this.label3.Location = new System.Drawing.Point(8, 136);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(112, 32);
            this.label3.TabIndex = 2;
            this.label3.Text = "Amount:";
            // label4
            this.label4.Location = new System.Drawing.Point(8, 184);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(104, 40);
            this.label4.TabIndex = 3;
            this.label4.Text = "Due To:";
            // textBox1
            this.textBox1.Location = new System.Drawing.Point(152, 24);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(128, 20);
            this.textBox1.TabIndex = 4;
            this.textBox1.Text = "textBox1";
            // textBox2
            this.textBox2.Location = new System.Drawing.Point(160, 80);
            this.textBox2.Name = "textBox2";
            this.textBox2.TabIndex = 5;
            this.textBox2.Text = "textBox2";
            // textBox3
            this.textBox3.Location = new System.Drawing.Point(160, 128);
            this.textBox3.Name = "textBox3";
            this.textBox3.Size = new System.Drawing.Size(112, 20);
            this.textBox3.TabIndex = 6;
            this.textBox3.Text = "textBox3";
            // textBox4
            this.textBox4.Location = new System.Drawing.Point(160, 184);
            this.textBox4.Name = "textBox4";
            this.textBox4.Size = new System.Drawing.Size(120, 20);
            this.textBox4.TabIndex = 7;
            this.textBox4.Text = "textBox4";
            // button1
            this.button1.Location = new System.Drawing.Point(8, 232);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(104, 40);
            this.button1.TabIndex = 8;
            this.button1.Text = "Send Payment";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // button2
            this.button2.Location = new System.Drawing.Point(160, 232);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(120, 40);
            this.button2.TabIndex = 9;
            this.button2.Text = "Process Payment";
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // Form1
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.textBox4);
            this.Controls.Add(this.textBox3);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
        }
        #endregion
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }
        private void button1_Click(object sender, System.EventArgs e)
        {
            Payment myPayment;
            myPayment.Payor = textBox1.Text;
            myPayment.Payee = textBox2.Text;
            myPayment.Amount = Convert.ToInt32(textBox3.Text);
            myPayment.DueDate = textBox4.Text;
            System.Messaging.Message msg = new System.Messaging.Message();
            msg.Body=myPayment;
            MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay");
            msgQ.Send(msg);
        }
        private void button2_Click(object sender, System.EventArgs e)
        {
            MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
            Payment myPayment=new Payment();
            Object o=new Object();
            System.Type[] arrTypes=new System.Type [2];
            arrTypes[0] = myPayment.GetType();
            arrTypes[1] = o.GetType();
            msgQ.Formatter = new XmlMessageFormatter(arrTypes);
            myPayment=((Payment)msgQ.Receive().Body);
            StringBuilder sb = new StringBuilder();
            sb.Append("Payment paid to: " + myPayment.Payor);
            sb.Append("\n");
            sb.Append("Paid by: " + myPayment.Payee);
            sb.Append("\n");
            sb.Append("Amount: $" + myPayment.Amount.ToString());
            sb.Append("\n");
            sb.Append("Due Date: " + Convert.ToDateTime(myPayment.DueDate));
            MessageBox.Show(sb.ToString(), "Message Received!");
        }
        public struct Payment
        {
            public string Payor,Payee;
            public int Amount;
            public string DueDate;
        }
    }
}

Nota:

El código debe cambiarse en Visual Studio 2005. Al crear un proyecto de Windows Forms, Visual C# agrega un formulario al proyecto de forma predeterminada. Este formulario se denomina Form1. Los dos archivos que representan el formulario se denominan Form1.cs y Form1.designer.cs. Escribe el código en Form1.cs. El archivo Designer.cs es donde el Diseñador de Windows Forms escribe el código que implementa todas las acciones que ha realizado agregando controles. Para obtener más información sobre el Diseñador de Windows Forms en Visual C# 2005, vea Crear un proyecto (Visual C#)

volver a la parte superior

Comprobación del código

  1. En el menú Depurar, haga clic en Iniciar.

  2. Escriba los valores en cada cuadro de texto y, a continuación, haga clic en Enviar pago.

  3. Vuelva a la consola de administración de equipos. Haga clic en la carpeta Mensajes de cola en Colas privadas bajo billpay y compruebe que MSMQ recibió un mensaje (indicado por un icono de sobre).

  4. Haga clic con el botón derecho en el mensaje, haga clic en Propiedades, y luego haga clic en la pestaña Cuerpo Observa el mensaje de pago.

    Nota:

    El contenido del mensaje de pago se serializa como XML.

  5. Vuelva a la aplicación windows de pago de facturación y, a continuación, haga clic en el botón Procesar pago . Verá un cuadro de mensaje que confirma la recepción de un mensaje y muestra el mensaje.

volver a la parte superior

Solución de problemas

  • La falta de una cola privada suele ser un problema solo en Windows 2000 Professional y Windows XP Professional. Windows 2000 Server y Windows XP Server permiten el uso de la cola pública.

  • Pasar los argumentos correctos a XMLMessageFormatter() puede ser complicado. En este ejemplo, se producen excepciones si el objeto o los tipos de pago no se incluyen en la matriz Type que se pasa al constructor.

volver a la parte superior