Использование Visual C# для записи в очередь сообщений Майкрософт и чтения из нее

В этой статье описывается запись и чтение из очереди сообщений Майкрософт (MSMQ) в Visual C#.

Исходная версия продукта: Очередь сообщений Майкрософт
Исходный номер базы знаний: 815811

В этой задаче

Сводка

В этой статье описываются следующие действия:

  • Создание сообщения и его отправка в MSMQ в приложении Windows.
  • Чтение из частной очереди и десериализация содержимого сообщения для отображения.

Требования

Ниже описаны рекомендуемые оборудование, программное обеспечение, сетевая инфраструктура, навыки и знания, а также необходимые пакеты обновления.

  • Одна из следующих операционных систем с установленным MSMQ (она входит в состав четырех операционных систем): Windows 2000 Professional (или Server) или Windows XP Professional (или Server).

В этой статье также предполагается, что вы знакомы со следующими:

  • MSMQ
  • Использование средств из командной строки

вернуться к началу

Запись в MSMQ и чтение из нее

Пространство System.Messaging имен в платформа .NET Framework содержит классы, которые необходимо выполнить для чтения и записи в MSMQ. Чтобы создать небольшое приложение Windows, которое имитирует систему оплаты счетов через Интернет, выполните следующие действия.

  1. Откройте Visual Studio .NET или Visual Studio 2005.

  2. Создайте новое приложение Windows в Visual C#, а затем назовите его MSMQ.

  3. Чтобы отобразить Обозреватель решений, если он не отображается, нажмите клавиши CTRL+ALT+L. В окне Обозреватель решений щелкните правой кнопкой мыши Ссылки, а затем выберите команду Добавить ссылку.

  4. На вкладке .NET выберите файлSystem.Messaging.dll в списке .dll файлов. Нажмите кнопку Выбрать, а затем нажмите кнопку ОК.

    Примечание.

    В Visual Studio 2005 щелкните файлSystem.Messaging.dll в списке библиотек DLL и нажмите кнопку ОК.

  5. Form1.cs открыт в режиме конструктора. Если он не открыт, дважды щелкните Form1.cs в Обозреватель решений.

  6. Нажмите клавиши CTRL+ALT+X, чтобы открыть панель элементов. На панели элементов щелкните вкладку Windows Forms.

  7. Из панели элементов перетащите следующую команду в середину Form1:

    • По четыре строки метки и текстового поля (расположены справа от каждой метки).
    • Под метками и текстовыми полями перетащите два элемента управления Button в Form1.
  8. Щелкните правой кнопкой мыши элементы управления, выберите пункт Свойства, а затем задайте для свойства Text для меток следующее (по порядку):

    • Платите по следующим сведениям:
    • Ваше имя:
    • Сумма:
    • Дата выполнения:
  9. В диалоговом окне Свойства задайте для свойства Text элемента button1 значение Отправить платеж, а для свойства Text элемента button2 задайте значение Обработка оплаты.

  10. Это приложение работает с частной очередью, которую необходимо сначала создать в консоли управления компьютером. Для этого выполните следующие действия:

    1. На рабочем столе щелкните правой кнопкой мыши Мой компьютер и выберите пункт Управление.
    2. Разверните узел Службы и приложения, чтобы найти MSMQ.

    Примечание.

    Если вы не нашли MSMQ, он не установлен.

  11. Разверните узел Очередь сообщений, щелкните правой кнопкой мыши Частные очереди, наведите указатель мыши на пункт Создать, а затем выберите Частная очередь.

  12. В поле Имя очереди введите billpay и нажмите кнопку ОК.

    Примечание.

    Не выбирайте поле Транзакционный проверка. Оставьте консоль управления компьютером открытой, так как вы вернелись к ней позже для просмотра сообщений.

  13. В верхней части кода в Form1 добавьте два USING оператора перед объявлением класса, чтобы включить дополнительные классы, которые находятся в System.Messaging пространстве имен и System.Text пространствах имен. (Пространство System.Text имен предназначено для использования StringBuilder класса , нового платформа .NET Framework класса, который лучше использовать при сцепление строк.)

    using System.Messaging;
    using System.Text;
    
  14. Создайте структуру, содержащую переменные для хранения данных, определяющих платеж. Чтобы создать структуру, добавьте следующий код после процедуры Main:

    public struct Payment
    {
        public string Payor,Payee;
        public int Amount;
        public string DueDate;
    }
    
  15. Добавьте код на следующих шагах в Click событие button1.

    1. Задайте для свойств структуры значения элементов формы следующим образом:

      Payment myPayment;
      myPayment.Payor = textBox1.Text;
      myPayment.Payee = textBox2.Text;
      myPayment.Amount = Convert.ToInt32(textBox3.Text);
      myPayment.DueDate = textBox4.Text;
      
    2. Создайте экземпляр Message класса , а затем присвойте свойству Body структуру payment :

      System.Messaging.Message msg = new System.Messaging.Message();
      msg.Body=myPayment;
      
    3. Чтобы отправить сообщение в MSMQ, создайте экземпляр MessageQueue класса и вызовите Send метод, который передает объект Message . Класс MessageQueue является оболочкой, которая управляет взаимодействием с MSMQ.

      Примечание.

      Синтаксис для задания пути к частной очереди, созданной в консоли управления компьютером. Частные очереди принимают форму machinename\Private$\queuename. На локальные компьютеры узлов ссылаются точка или точка (отображается как .).

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

      Теперь существует код для отправки сообщения в MSMQ. платформа .NET Framework автоматически сериализует сообщение с помощью XMLMessageFormatter объекта . Этот объект неявно создается при отправке сообщений.

  16. Добавьте код на следующих шагах в Click событие button2. Обработчик button2_Click событий получает и обрабатывает платежное сообщение, отправляемое в обработчик событий button1 .

    1. Первая строка кода совпадает со строкой кода, которая находится в первом обработчике событий:

      MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
      
    2. Создайте массив типов для передачи в 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 как десериализовать сообщение.

    3. Сообщения получаются путем 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));
      
    4. Создайте окно сообщения для отображения результатов:

      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#)

вернуться к началу

Проверка кода

  1. В меню Отладка нажмите кнопку Пуск.

  2. Введите значения в каждое текстовое поле и нажмите кнопку Отправить платеж.

  3. Вернитесь в консоль управления компьютером. Щелкните папку Сообщения очереди в разделе Частные очереди в разделе выставлениесчетов, а затем убедитесь, что MSMQ получил сообщение (указано значком конверта).

  4. Щелкните сообщение правой кнопкой мыши, выберите пункт Свойства и перейдите на вкладку Текст . Вы заметили сообщение об оплате.

    Примечание.

    Содержимое сообщения об оплате сериализуется в формате XML.

  5. Вернитесь к приложению windows для оплаты счетов и нажмите кнопку Обработать оплату . Появится окно сообщения, которое подтверждает получение сообщения и отображает его.

вернуться к началу

Устранение неполадок

  • Отсутствие частной очереди обычно является проблемой только в Windows 2000 Professional и Windows XP Professional. Windows 2000 Server и Windows XP Server разрешают использование общедоступной очереди.

  • Передача правильных аргументов XMLMessageFormatter() в может быть сложной задачей. В этом примере исключения создаются, если объект или типы платежей не включены в массив Type, передаваемый конструктору.

вернуться к началу