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
- Requisitos
- Gravar e ler do MSMQ
- Listagem de código completa (Form1.cs)
- Verificar o código
- Solução de problemas
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
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:
Abra o Visual Studio .NET ou o Visual Studio 2005.
Crie um novo aplicativo windows no Visual C#e nomeie-o MSMQ.
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.
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.
Form1.cs está aberto na exibição Design. Se não estiver aberto, clique duas vezes em Form1.cs no Gerenciador de Soluções.
Pressione CTRL+ALT+X para abrir a caixa de ferramentas. Na caixa de ferramentas, clique na guia Windows Forms.
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.
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:
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.
Esse aplicativo funciona com uma fila privada que você deve primeiro criar no console de Gerenciamento de Computadores. Para fazer isso, siga estas etapas:
- Na área de trabalho, clique com o botão direito do mouse em Meu Computador e clique em Gerenciar.
- 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.
Expanda a Fila de Mensagens, clique com o botão direito do mouse em Filas Privadas, aponte para Novo e clique em Fila Privada.
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.
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 noSystem.Messaging
namespace e nosSystem.Text
namespaces. (OSystem.Text
namespace é para o uso daStringBuilder
classe, uma nova classe .NET Framework que é melhor usar quando você concatenar cadeias de caracteres.)using System.Messaging; using System.Text;
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; }
Adicione o código nas etapas a seguir ao
Click
evento debutton1
.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;
Crie uma instância da
Message
classe e defina aBody
propriedade como apayment
estrutura:System.Messaging.Message msg = new System.Messaging.Message(); msg.Body=myPayment;
Para enviar uma mensagem ao MSMQ, crie uma instância da
MessageQueue
classe e chame oSend
método que passa noMessage
objeto. AMessageQueue
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.
Adicione o código nas etapas a seguir ao
Click
evento do botão2. Obutton2_Click
manipulador de eventos recebe e processa a mensagem de pagamento enviada no manipulador debutton1
eventos.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");
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, umaType
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.As mensagens são recebidas chamando o
Receive
método. Acesse aBody
propriedade para ler o conteúdo da mensagem. ABody
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));
Crie uma caixa de mensagem para exibir os resultados:
MessageBox.Show(sb.ToString(), "Message Received!");
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#)
Verificar o código
No menu Depuração , clique em Iniciar.
Digite valores em cada caixa de texto e clique em Enviar Pagamento.
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).
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.
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.
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.