Usar o Visual C# para gravar e ler na Fila de Mensagens da Microsoft

Este artigo descreve como gravar e ler no MSMQ (Enfileiramento de Mensagens da Microsoft) no Visual C#.

Versão original do produto: Enfileiramento de mensagens da Microsoft
Número de KB original: 815811

Nesta tarefa

Resumo

Este artigo descreve o seguinte:

  • Como criar uma mensagem e enviá-la para o MSMQ em um aplicativo windows.
  • Como ler de uma fila privada e desserializar o conteúdo da mensagem para exibição.

Requisitos

Os itens a seguir descrevem o hardware, o software, a infraestrutura de rede, as habilidades e os conhecimentos e os pacotes de serviço recomendados que são necessários:

  • Um dos seguintes sistemas operacionais com o MSMQ instalado (ele está incluído como uma opção nos quatro sistemas operacionais): Windows 2000 Professional (ou Server) ou Windows XP Professional (ou Server).

Este artigo também pressupõe que você esteja familiarizado com o seguinte:

  • MSMQ
  • Usando ferramentas do prompt de comando

de volta à parte superior

Gravar e ler do MSMQ

O System.Messaging namespace no .NET Framework tem as classes das quais você deve ler e gravar no MSMQ. Para criar um pequeno aplicativo Windows que imita um sistema de pagamento de cobrança online, siga estas etapas:

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

  2. Crie um novo aplicativo windows no Visual C#e nomeie-o MSMQ.

  3. Para exibir Gerenciador de Soluções se ele não aparecer, pressione CTRL+ALT+L. No Gerenciador de Soluções, clique com o botão direito do mouse em Referências e clique em Adicionar Referência.

  4. Na guia .NET , selecione o arquivoSystem.Messaging.dll na lista de arquivos .dll . Clique em Selecionar e clique em OK.

    Observação

    No Visual Studio 2005, clique no arquivo System.Messaging.dll na lista de DLLs e clique em OK.

  5. Form1.cs está aberto na exibição Design. Se não estiver aberto, clique duas vezes em Form1.cs no Gerenciador de Soluções.

  6. Pressione CTRL+ALT+X para abrir a caixa de ferramentas. Na caixa de ferramentas, clique na guia Windows Forms.

  7. Na caixa de ferramentas, arraste o seguinte para o meio do Form1:

    • Quatro linhas cada uma de um Rótulo e uma Caixa de Texto (posicionada à direita de cada rótulo).
    • Nos rótulos e caixas de texto, arraste dois controles de botão para o Form1.
  8. Clique com o botão direito do mouse nos controles, clique em Propriedades e defina a propriedade Text para os rótulos a seguir (em ordem):

    • Pagar para:
    • Seu nome:
    • Quantidade:
    • Data de vencimento:
  9. Na caixa de diálogo Propriedades , defina a propriedade Texto do botão1 como Enviar Pagamento e defina a propriedade Texto do botão2 como Processar Pagamento.

  10. Esse aplicativo funciona com uma fila privada que você deve primeiro criar no console de Gerenciamento de Computadores. Para fazer isso, siga estas etapas:

    1. Na área de trabalho, clique com o botão direito do mouse em Meu Computador e clique em Gerenciar.
    2. Expanda o nó Serviços e Aplicativos para localizar o MSMQ.

    Observação

    Se você não encontrar o MSMQ, ele não será instalado.

  11. Expanda a Fila de Mensagens, clique com o botão direito do mouse em Filas Privadas, aponte para Novo e clique em Fila Privada.

  12. Na caixa Nome da fila , digite pagamento de cobrança e clique em OK.

    Observação

    Não selecione a caixa marcar transacional. Deixe o console de Gerenciamento de Computador aberto porque você retornará a ele mais tarde para exibir mensagens.

  13. Na parte superior do código no Form1, adicione duas USING instruções antes da declaração de classe para incluir as classes adicionais que residem no System.Messaging namespace e nos System.Text namespaces. (O System.Text namespace é para o uso da StringBuilder classe, uma nova classe .NET Framework que é melhor usar quando você concatenar cadeias de caracteres.)

    using System.Messaging;
    using System.Text;
    
  14. Crie uma estrutura que contenha variáveis para manter os dados que definem um pagamento. Para criar a estrutura, adicione o seguinte código após o procedimento Principal:

    public struct Payment
    {
        public string Payor,Payee;
        public int Amount;
        public string DueDate;
    }
    
  15. Adicione o código nas etapas a seguir ao Click evento de button1.

    1. Defina as propriedades da estrutura como valores dos elementos de formulário da seguinte maneira:

      Payment myPayment;
      myPayment.Payor = textBox1.Text;
      myPayment.Payee = textBox2.Text;
      myPayment.Amount = Convert.ToInt32(textBox3.Text);
      myPayment.DueDate = textBox4.Text;
      
    2. Crie uma instância da Message classe e defina a Body propriedade como a payment estrutura:

      System.Messaging.Message msg = new System.Messaging.Message();
      msg.Body=myPayment;
      
    3. Para enviar uma mensagem ao MSMQ, crie uma instância da MessageQueue classe e chame o Send método que passa no Message objeto. A MessageQueue classe é o wrapper que gerencia a interação com o MSMQ.

      Observação

      A sintaxe para definir o caminho da fila privada que você criou no console de Gerenciamento de Computadores. Filas privadas tomam o formulário machinename\Private$\queuename. Os computadores host locais são referenciados com um ponto ou um período (mostrado como .).

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

      O código agora existe para enviar uma mensagem ao MSMQ. O .NET Framework serializa automaticamente a mensagem usando um XMLMessageFormatter objeto. Esse objeto é criado implicitamente quando as mensagens são enviadas.

  16. Adicione o código nas etapas a seguir ao Click evento do botão2. O button2_Click manipulador de eventos recebe e processa a mensagem de pagamento enviada no manipulador de button1 eventos.

    1. A primeira linha de código é a mesma que a linha de código que está no primeiro manipulador de eventos:

      MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
      
    2. Crie uma matriz de tipos para passar para a XMLMessageFormatter classe.

      Observação

      Essa classe deve ser criada explicitamente ao receber mensagens. O construtor da XMLMessageFormatter classe usa uma matriz de cadeia de caracteres de nomes de tipo ou, de preferência, uma 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);
      

      Esses tipos dizem XMLMessageFormatter como desserializar a mensagem.

    3. As mensagens são recebidas chamando o Receive método. Acesse a Body propriedade para ler o conteúdo da mensagem. A Body propriedade retorna um objeto, portanto, o objeto precisa ser lançado para o tipo de pagamento para recuperar o conteúdo em uma forma utilizável:

      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. Crie uma caixa de mensagem para exibir os resultados:

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

de volta à parte superior

Listagem 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;
        }
    }
}

Observação

O código deve ser alterado no Visual Studio 2005. Quando você cria um projeto Windows Forms, o Visual C# adiciona um formulário ao projeto por padrão. Esse formulário se chama Form1. Os dois arquivos que representam o formulário são nomeados Form1.cs e Form1.designer.cs. Você grava seu código em Form1.cs. O arquivo Designer.cs é onde o Windows Forms Designer grava o código que implementa todas as ações executadas adicionando controles. Para obter mais informações sobre o Windows Forms Designer no Visual C# 2005, consulte Criando um projeto (Visual C#)

de volta à parte superior

Verificar o código

  1. No menu Depuração , clique em Iniciar.

  2. Digite valores em cada caixa de texto e clique em Enviar Pagamento.

  3. Retorne ao console de Gerenciamento de Computadores. Clique na pasta Mensagens de Fila em Filas Privadas sob pagamento de cobrança e verifique se o MSMQ recebeu uma mensagem (indicada por um ícone de envelope).

  4. Clique com o botão direito do mouse na mensagem, clique em Propriedades e clique na guia Corpo . Você nota a mensagem de pagamento.

    Observação

    O conteúdo da mensagem de pagamento é serializado como XML.

  5. Retorne ao aplicativo Windows de pagamento de cobrança e clique no botão Processar Pagamento . Você vê uma caixa de mensagem que confirma o recebimento de uma mensagem e exibe a mensagem.

de volta à parte superior

Solução de problemas

  • A falta de uma fila privada geralmente é um problema apenas no Windows 2000 Professional e no Windows XP Professional. O Windows 2000 Server e o Windows XP Server permitem o uso da fila pública.

  • Passar os argumentos corretos para XMLMessageFormatter() pode ser complicado. Neste exemplo, exceções serão geradas se o objeto ou os Tipos de Pagamento não estiverem incluídos na matriz Type que é passada para o construtor.

de volta à parte superior