Использование Visual C# для записи в очередь сообщений Майкрософт и чтения из нее
В этой статье описывается запись и чтение из очереди сообщений Майкрософт (MSMQ) в Visual C#.
Исходная версия продукта: Очередь сообщений Майкрософт
Исходный номер базы знаний: 815811
В этой задаче
- Summary
- Требования
- Запись в MSMQ и чтение из нее
- Полный список кода (Form1.cs)
- Проверка кода
- Устранение неполадок
Сводка
В этой статье описываются следующие действия:
- Создание сообщения и его отправка в MSMQ в приложении Windows.
- Чтение из частной очереди и десериализация содержимого сообщения для отображения.
Требования
Ниже описаны рекомендуемые оборудование, программное обеспечение, сетевая инфраструктура, навыки и знания, а также необходимые пакеты обновления.
- Одна из следующих операционных систем с установленным MSMQ (она входит в состав четырех операционных систем): Windows 2000 Professional (или Server) или Windows XP Professional (или Server).
В этой статье также предполагается, что вы знакомы со следующими:
- MSMQ
- Использование средств из командной строки
Запись в MSMQ и чтение из нее
Пространство System.Messaging
имен в платформа .NET Framework содержит классы, которые необходимо выполнить для чтения и записи в MSMQ. Чтобы создать небольшое приложение Windows, которое имитирует систему оплаты счетов через Интернет, выполните следующие действия.
Откройте Visual Studio .NET или Visual Studio 2005.
Создайте новое приложение Windows в Visual C#, а затем назовите его MSMQ.
Чтобы отобразить Обозреватель решений, если он не отображается, нажмите клавиши CTRL+ALT+L. В окне Обозреватель решений щелкните правой кнопкой мыши Ссылки, а затем выберите команду Добавить ссылку.
На вкладке .NET выберите файлSystem.Messaging.dll в списке .dll файлов. Нажмите кнопку Выбрать, а затем нажмите кнопку ОК.
Примечание.
В Visual Studio 2005 щелкните файлSystem.Messaging.dll в списке библиотек DLL и нажмите кнопку ОК.
Form1.cs открыт в режиме конструктора. Если он не открыт, дважды щелкните Form1.cs в Обозреватель решений.
Нажмите клавиши CTRL+ALT+X, чтобы открыть панель элементов. На панели элементов щелкните вкладку Windows Forms.
Из панели элементов перетащите следующую команду в середину Form1:
- По четыре строки метки и текстового поля (расположены справа от каждой метки).
- Под метками и текстовыми полями перетащите два элемента управления Button в Form1.
Щелкните правой кнопкой мыши элементы управления, выберите пункт Свойства, а затем задайте для свойства Text для меток следующее (по порядку):
- Платите по следующим сведениям:
- Ваше имя:
- Сумма:
- Дата выполнения:
В диалоговом окне Свойства задайте для свойства Text элемента button1 значение Отправить платеж, а для свойства Text элемента button2 задайте значение Обработка оплаты.
Это приложение работает с частной очередью, которую необходимо сначала создать в консоли управления компьютером. Для этого выполните следующие действия:
- На рабочем столе щелкните правой кнопкой мыши Мой компьютер и выберите пункт Управление.
- Разверните узел Службы и приложения, чтобы найти MSMQ.
Примечание.
Если вы не нашли MSMQ, он не установлен.
Разверните узел Очередь сообщений, щелкните правой кнопкой мыши Частные очереди, наведите указатель мыши на пункт Создать, а затем выберите Частная очередь.
В поле Имя очереди введите billpay и нажмите кнопку ОК.
Примечание.
Не выбирайте поле Транзакционный проверка. Оставьте консоль управления компьютером открытой, так как вы вернелись к ней позже для просмотра сообщений.
В верхней части кода в Form1 добавьте два
USING
оператора перед объявлением класса, чтобы включить дополнительные классы, которые находятся вSystem.Messaging
пространстве имен иSystem.Text
пространствах имен. (ПространствоSystem.Text
имен предназначено для использованияStringBuilder
класса , нового платформа .NET Framework класса, который лучше использовать при сцепление строк.)using System.Messaging; using System.Text;
Создайте структуру, содержащую переменные для хранения данных, определяющих платеж. Чтобы создать структуру, добавьте следующий код после процедуры Main:
public struct Payment { public string Payor,Payee; public int Amount; public string DueDate; }
Добавьте код на следующих шагах в
Click
событиеbutton1
.Задайте для свойств структуры значения элементов формы следующим образом:
Payment myPayment; myPayment.Payor = textBox1.Text; myPayment.Payee = textBox2.Text; myPayment.Amount = Convert.ToInt32(textBox3.Text); myPayment.DueDate = textBox4.Text;
Создайте экземпляр
Message
класса , а затем присвойте свойствуBody
структуруpayment
:System.Messaging.Message msg = new System.Messaging.Message(); msg.Body=myPayment;
Чтобы отправить сообщение в MSMQ, создайте экземпляр
MessageQueue
класса и вызовитеSend
метод, который передает объектMessage
. КлассMessageQueue
является оболочкой, которая управляет взаимодействием с MSMQ.Примечание.
Синтаксис для задания пути к частной очереди, созданной в консоли управления компьютером. Частные очереди принимают форму
machinename\Private$\queuename
. На локальные компьютеры узлов ссылаются точка или точка (отображается как .).MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay"); msgQ.Send(msg);
Теперь существует код для отправки сообщения в MSMQ. платформа .NET Framework автоматически сериализует сообщение с помощью
XMLMessageFormatter
объекта . Этот объект неявно создается при отправке сообщений.
Добавьте код на следующих шагах в
Click
событие button2. Обработчикbutton2_Click
событий получает и обрабатывает платежное сообщение, отправляемое в обработчик событийbutton1
.Первая строка кода совпадает со строкой кода, которая находится в первом обработчике событий:
MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
Создайте массив типов для передачи в
XMLMessageFormatter
класс.Примечание.
Этот класс должен быть создан явным образом при получении сообщений. Конструктор
XMLMessageFormatter
класса принимает либо строковый массив имен типов, либо, что более предпочтительно,Type
массив типов: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);
Эти типы сообщают,
XMLMessageFormatter
как десериализовать сообщение.Сообщения получаются путем
Receive
вызова метода . Доступ к свойствуBody
для чтения содержимого сообщения. Свойство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!");
Полный список кода (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;
}
}
}
Примечание.
Код необходимо изменить в Visual Studio 2005. При создании проекта Windows Forms Visual C# добавляет в проект одну форму по умолчанию. Эта форма называется Form1. Два файла, которые представляют форму, называются Form1.cs и Form1.designer.cs. Вы пишете код в Form1.cs. В файле Designer.cs Windows Forms Designer записывается код, который реализует все действия, выполняемые путем добавления элементов управления. Дополнительные сведения о Windows Forms Designer в Visual C# 2005 см. в статье Создание проекта (Visual C#)
Проверка кода
В меню Отладка нажмите кнопку Пуск.
Введите значения в каждое текстовое поле и нажмите кнопку Отправить платеж.
Вернитесь в консоль управления компьютером. Щелкните папку Сообщения очереди в разделе Частные очереди в разделе выставлениесчетов, а затем убедитесь, что MSMQ получил сообщение (указано значком конверта).
Щелкните сообщение правой кнопкой мыши, выберите пункт Свойства и перейдите на вкладку Текст . Вы заметили сообщение об оплате.
Примечание.
Содержимое сообщения об оплате сериализуется в формате XML.
Вернитесь к приложению windows для оплаты счетов и нажмите кнопку Обработать оплату . Появится окно сообщения, которое подтверждает получение сообщения и отображает его.
Устранение неполадок
Отсутствие частной очереди обычно является проблемой только в Windows 2000 Professional и Windows XP Professional. Windows 2000 Server и Windows XP Server разрешают использование общедоступной очереди.
Передача правильных аргументов
XMLMessageFormatter()
в может быть сложной задачей. В этом примере исключения создаются, если объект или типы платежей не включены в массив Type, передаваемый конструктору.