Visual C# を使用して Microsoft メッセージ キューへの書き込みと読み取りを行う

この記事では、Visual C# で Microsoft Message Queuing (MSMQ) への書き込みと読み取りを行う方法について説明します。

元の製品バージョン: Microsoft メッセージ キュー
元の KB 番号: 815811

このタスクでは、

概要

この記事では、以下について説明します。

  • メッセージを作成し、Windows アプリケーションで MSMQ に送信する方法。
  • プライベート キューから読み取り、メッセージの内容を逆シリアル化して表示する方法。

要件

次の項目では、推奨されるハードウェア、ソフトウェア、ネットワーク インフラストラクチャ、スキルと知識、および必要なサービス パックについて説明します。

  • MSMQ がインストールされている次のいずれかのオペレーティング システム (Windows 2000 Professional (または Server)、または Windows XP Professional (またはサーバー) の 4 つのオペレーティング システムにオプションとして含まれています)。

この記事では、次の点についても理解していることを前提としています。

  • MSMQ
  • コマンド プロンプトからツールを使用する

先頭に戻る

MSMQ への書き込みと MSMQ からの読み取り

System.Messaging.NET Frameworkの名前空間には、MSMQ から読み取って書き込む必要があるクラスがあります。 オンライン請求書支払いシステムを模倣する小さな Windows アプリケーションを作成するには、次の手順に従います。

  1. Visual Studio .NET または Visual Studio 2005 を開きます。

  2. Visual C# で新しい Windows アプリケーションを作成し、 MSMQ という名前を付けます。

  3. 表示されない場合ソリューション エクスプローラーを表示するには、Ctrl キーを押しながら Alt キーを押しながら L キーを押します。 ソリューション エクスプローラーで [参照] を右クリックし、[参照の追加] をクリックします。

  4. [.NET] タブで、.dll ファイルの一覧で System.Messaging.dllファイルを選択します。 [ 選択] をクリックし、[OK] をクリック します

    注:

    Visual Studio 2005 で、DLL の一覧で System.Messaging.dll ファイルをクリックし、[OK] をクリック します

  5. Form1.cs はデザイン ビューで開いています。 開かない場合は、ソリューション エクスプローラーでForm1.csをダブルクリックします。

  6. Ctrl + Alt + X キーを押してツールボックスを開きます。 [ツールボックス] で、[Windows フォーム] タブをクリックします。

  7. ツールボックスから、次を Form1 の中央にドラッグします。

    • ラベルとテキスト ボックスのそれぞれ 4 行 (各ラベルの右側に配置)。
    • ラベルとテキスト ボックスの下で、2 つのボタン コントロールを Form1 にドラッグします。
  8. コントロールを右クリックし、[ プロパティ] をクリックし、ラベルの Text プロパティを次の (順番に) に設定します。

    • 支払い対象:
    • お名前 *:
    • 量:
    • 期限:
  9. [ プロパティ ] ダイアログ ボックスで、button1 の Text プロパティを [支払いの送信] に設定し、button2 の Text プロパティを [支払いの処理] に設定します。

  10. このアプリケーションは、コンピューター管理コンソールで最初に作成する必要があるプライベート キューで動作します。 これを行うには、次の手順を実行します。

    1. デスクトップで、[ マイ コンピューター] を右クリックし、[ 管理] をクリックします。
    2. [ サービスとアプリケーション] ノードを 展開して MSMQ を見つけます。

    注:

    MSMQ が見つからない場合は、インストールされていません。

  11. [メッセージ キュー] を展開し、[プライベート キュー] を右クリックし、[新規] をポイントして、[プライベート キュー] をクリックします。

  12. [ キュー名 ] ボックスに「 billpay」と入力し、[OK] をクリック します

    注:

    [トランザクション チェック] ボックスは選択しないでください。 後でメッセージを表示するためにコンピューター管理コンソールに戻るため、コンピューター管理コンソールは開いたままにします。

  13. Form1 のコードの先頭に、クラス宣言の前に 2 つの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. のイベントbutton1に、次の手順のコードをClick追加します。

    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. button2 のイベントに、次の手順のコードを Click 追加します。 イベント ハンドラーは 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 フォーム プロジェクトを作成すると、Visual C# は既定で 1 つのフォームをプロジェクトに追加します。 このフォームの名前は Form1 です。 フォームを表す 2 つのファイルには、 Form1.cs と Form1.designer.cs という名前が付 けられますForm1.csでコードを記述します。 Designer.cs ファイルは、コントロールを追加して実行したすべてのアクションを実装するコードをWindows フォーム Designerが書き込む場所です。 Visual C# 2005 のWindows フォーム Designerの詳細については、「プロジェクトの作成 (Visual C#)」を参照してください。

先頭に戻る

コードを確認する

  1. [ デバッグ ] メニューの [ 開始] をクリックします。

  2. 各テキスト ボックスに値を入力し、[ 支払いの送信] をクリックします。

  3. コンピューター管理コンソールに戻ります。 [billpay] の [プライベート キュー] の [キュー メッセージ] フォルダーをクリックし、MSMQ がメッセージを受信したことを確認します (エンベロープ アイコンで示されます)。

  4. メッセージを右クリックし、[ プロパティ] をクリックし、[ 本文 ] タブをクリックします。支払いメッセージが表示されます。

    注:

    支払いメッセージの内容は XML としてシリアル化されます。

  5. 請求書支払い Windows アプリケーションに戻り、[ 支払いの処理 ] ボタンをクリックします。 メッセージの受信を確認し、メッセージを表示するメッセージ ボックスが表示されます。

先頭に戻る

トラブルシューティング

  • プライベート キューの欠如は、一般に、Windows 2000 Professional と Windows XP Professional でのみ発生する問題です。 Windows 2000 Server と Windows XP Server では、パブリック キューの使用が許可されます。

  • 正しい引数を に XMLMessageFormatter() 渡すのは難しい場合があります。 この例では、オブジェクトまたは支払い型のいずれかがコンストラクターに渡される Type 配列に含まれていない場合、例外がスローされます。

先頭に戻る