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 アプリケーションを作成するには、次の手順に従います。
Visual Studio .NET または Visual Studio 2005 を開きます。
Visual C# で新しい Windows アプリケーションを作成し、 MSMQ という名前を付けます。
表示されない場合ソリューション エクスプローラーを表示するには、Ctrl キーを押しながら Alt キーを押しながら L キーを押します。 ソリューション エクスプローラーで [参照] を右クリックし、[参照の追加] をクリックします。
[.NET] タブで、.dll ファイルの一覧で System.Messaging.dllファイルを選択します。 [ 選択] をクリックし、[OK] をクリック します。
注:
Visual Studio 2005 で、DLL の一覧で System.Messaging.dll ファイルをクリックし、[OK] をクリック します。
Form1.cs はデザイン ビューで開いています。 開かない場合は、ソリューション エクスプローラーでForm1.csをダブルクリックします。
Ctrl + Alt + X キーを押してツールボックスを開きます。 [ツールボックス] で、[Windows フォーム] タブをクリックします。
ツールボックスから、次を Form1 の中央にドラッグします。
- ラベルとテキスト ボックスのそれぞれ 4 行 (各ラベルの右側に配置)。
- ラベルとテキスト ボックスの下で、2 つのボタン コントロールを Form1 にドラッグします。
コントロールを右クリックし、[ プロパティ] をクリックし、ラベルの Text プロパティを次の (順番に) に設定します。
- 支払い対象:
- お名前 *:
- 量:
- 期限:
[ プロパティ ] ダイアログ ボックスで、button1 の Text プロパティを [支払いの送信] に設定し、button2 の Text プロパティを [支払いの処理] に設定します。
このアプリケーションは、コンピューター管理コンソールで最初に作成する必要があるプライベート キューで動作します。 これを行うには、次の手順を実行します。
- デスクトップで、[ マイ コンピューター] を右クリックし、[ 管理] をクリックします。
- [ サービスとアプリケーション] ノードを 展開して MSMQ を見つけます。
注:
MSMQ が見つからない場合は、インストールされていません。
[メッセージ キュー] を展開し、[プライベート キュー] を右クリックし、[新規] をポイントして、[プライベート キュー] をクリックします。
[ キュー名 ] ボックスに「 billpay」と入力し、[OK] をクリック します。
注:
[トランザクション チェック] ボックスは選択しないでください。 後でメッセージを表示するためにコンピューター管理コンソールに戻るため、コンピューター管理コンソールは開いたままにします。
Form1 のコードの先頭に、クラス宣言の前に 2 つの
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; }
のイベント
button1
に、次の手順のコードをClick
追加します。次のように、構造体のプロパティをフォーム要素の値に設定します。
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
シリアル化します。 このオブジェクトは、メッセージが送信されるときに暗黙的に作成されます。
button2 のイベントに、次の手順のコードを
Click
追加します。 イベント ハンドラーは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 フォーム プロジェクトを作成すると、Visual C# は既定で 1 つのフォームをプロジェクトに追加します。 このフォームの名前は Form1 です。 フォームを表す 2 つのファイルには、 Form1.cs と Form1.designer.cs という名前が付 けられます。 Form1.csでコードを記述します。 Designer.cs ファイルは、コントロールを追加して実行したすべてのアクションを実装するコードをWindows フォーム Designerが書き込む場所です。 Visual C# 2005 のWindows フォーム Designerの詳細については、「プロジェクトの作成 (Visual C#)」を参照してください。
コードを確認する
[ デバッグ ] メニューの [ 開始] をクリックします。
各テキスト ボックスに値を入力し、[ 支払いの送信] をクリックします。
コンピューター管理コンソールに戻ります。 [billpay] の [プライベート キュー] の [キュー メッセージ] フォルダーをクリックし、MSMQ がメッセージを受信したことを確認します (エンベロープ アイコンで示されます)。
メッセージを右クリックし、[ プロパティ] をクリックし、[ 本文 ] タブをクリックします。支払いメッセージが表示されます。
注:
支払いメッセージの内容は XML としてシリアル化されます。
請求書支払い Windows アプリケーションに戻り、[ 支払いの処理 ] ボタンをクリックします。 メッセージの受信を確認し、メッセージを表示するメッセージ ボックスが表示されます。
トラブルシューティング
プライベート キューの欠如は、一般に、Windows 2000 Professional と Windows XP Professional でのみ発生する問題です。 Windows 2000 Server と Windows XP Server では、パブリック キューの使用が許可されます。
正しい引数を に
XMLMessageFormatter()
渡すのは難しい場合があります。 この例では、オブジェクトまたは支払い型のいずれかがコンストラクターに渡される Type 配列に含まれていない場合、例外がスローされます。