Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird beschrieben, wie Sie in Microsoft Message Queuing (MSMQ) in Visual C# schreiben und lesen.
Originalproduktversion: Microsoft Message Queuing
Ursprüngliche KB-Nummer: 815811
In dieser Aufgabe
- Zusammenfassung
- Anforderungen
- Schreiben in und Lesen von MSMQ
- Vollständige Codeauflistung (Form1.cs)
- Überprüfen des Codes
- Problembehandlung
Übersicht
In diesem Artikel wird Folgendes beschrieben:
- Erstellen einer Nachricht und Senden an MSMQ in einer Windows-Anwendung
- So lesen Sie aus einer privaten Warteschlange und deserialisieren Sie die Nachrichteninhalte zur Anzeige.
Anforderungen
Die folgenden Elemente beschreiben die empfohlene Hardware, Software, Netzwerkinfrastruktur, Fähigkeiten und Kenntnisse sowie Service Packs, die erforderlich sind:
- Eines der folgenden Betriebssysteme, auf dem MSMQ installiert ist (es ist als Option auf den vier Betriebssystemen enthalten): Windows 2000 Professional (oder Server) oder Windows XP Professional (oder Server).
In diesem Artikel wird auch davon ausgegangen, dass Sie mit den folgenden Schritten vertraut sind:
- MSMQ
- Verwenden von Tools aus der Eingabeaufforderung
In MSMQ schreiben und aus MSMQ lesen
Der System.Messaging
Namespace in der .NET Framework enthält die Klassen, die Sie benötigen, um von MSMQ zu lesen und darauf zu schreiben. Führen Sie die folgenden Schritte aus, um eine kleine Windows-Anwendung zu erstellen, die ein Onlinerechnungszahlungssystem nachahmt:
Öffnen Sie Visual Studio .NET oder Visual Studio 2005.
Erstellen Sie eine neue Windows-Anwendung in Visual C#, und nennen Sie sie "MSMQ".
Um den Projektmappen-Explorer anzuzeigen, wenn er nicht erscheint, drücken Sie STRG+ALT+L. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Verweise, und klicken Sie dann auf Verweis hinzufügen.
Wählen Sie auf der Registerkarte .NET die System.Messaging.dll Datei in der Liste der .dll Dateien aus. Klicken Sie auf "Auswählen", und klicken Sie dann auf "OK".
Notiz
Klicken Sie in Visual Studio 2005 in der Liste der DLLs auf die System.Messaging.dll Datei, und klicken Sie dann auf OK.
Form1.cs ist in der Entwurfsansicht geöffnet. Wenn es nicht geöffnet ist, doppelklicken Sie im Projektmappen-Explorer auf Form1.cs.
Drücken Sie STRG+ALT+X, um die Toolbox zu öffnen. Klicken Sie in der Toolbox auf die Registerkarte "Windows Forms".
Ziehen Sie in der Toolbox Folgendes in die Mitte von Form1:
- Jeweils vier Zeilen einer Beschriftung und eines Textfelds (rechts neben jeder Beschriftung positioniert).
- Ziehen Sie unter den Beschriftungen und Textfeldern zwei Schaltflächensteuerelemente auf Form1.
Klicken Sie mit der rechten Maustaste auf die Steuerelemente, klicken Sie auf Eigenschaften, und legen Sie dann die Text-Eigenschaft für die Beschriftungen auf Folgendes fest (in der Reihenfolge):
- Zahlung an:
- Ihr Name:
- Menge:
- Fälligkeitsdatum:
Legen Sie im Dialogfeld "Eigenschaften " die Texteigenschaft von "Button1" auf " Zahlung senden" fest, und legen Sie die Texteigenschaft von "Button2" auf " Zahlung verarbeiten" fest.
Diese Anwendung funktioniert mit einer privaten Warteschlange, die Sie zuerst in der Computerverwaltungskonsole erstellen müssen. Gehen Sie dazu wie folgt vor:
- Klicken Sie auf dem Desktop mit der rechten Maustaste auf "Arbeitsplatz", und klicken Sie dann auf "Verwalten".
- Erweitern Sie den Knoten "Dienste und Anwendungen ", um MSMQ zu finden.
Notiz
Wenn Sie MSMQ nicht finden, ist sie nicht installiert.
Erweitern Sie Message Queuing, klicken Sie mit der rechten Maustaste auf Private Warteschlangen, zeigen Sie auf Neu, und klicken Sie dann auf Private Warteschlange.
Geben Sie im Feld "Warteschlangenname" den Namen "Billpay" ein, und klicken Sie dann auf "OK".
Notiz
Aktivieren Sie nicht das Kontrollkästchen Transaktion. Lassen Sie die Computerverwaltungskonsole geöffnet, da Sie später zur Anzeige von Nachrichten zurückkehren.
Fügen Sie oben im Code in Form1 zwei
USING
Anweisungen vor der Klassendeklaration hinzu, um die zusätzlichen Klassen einzuschließen, die sich imSystem.Messaging
Namespace und denSystem.Text
Namespaces befinden. (DerSystem.Text
Namespace dient der Verwendung derStringBuilder
Klasse, einer neuen .NET Framework-Klasse, die beim Verketten von Zeichenfolgen am besten verwendet werden soll.)using System.Messaging; using System.Text;
Erstellen Sie eine Struktur, die Variablen enthält, um die Daten zu enthalten, die eine Zahlung definieren. Um die Struktur zu erstellen, fügen Sie den folgenden Code nach der Hauptprozedur hinzu:
public struct Payment { public string Payor,Payee; public int Amount; public string DueDate; }
Fügen Sie den Code in den folgenden Schritten zum
Click
Ereignis vonbutton1
.Legen Sie die Eigenschaften der Struktur auf Werte der Formularelemente wie folgt fest:
Payment myPayment; myPayment.Payor = textBox1.Text; myPayment.Payee = textBox2.Text; myPayment.Amount = Convert.ToInt32(textBox3.Text); myPayment.DueDate = textBox4.Text;
Erstellen Sie eine Instanz der
Message
Klasse, und legen Sie dann dieBody
Eigenschaft auf diepayment
Struktur fest:System.Messaging.Message msg = new System.Messaging.Message(); msg.Body=myPayment;
Um eine Nachricht an MSMQ zu senden, erstellen Sie eine Instanz der
MessageQueue
Klasse, und rufen Sie die Methode auf, dieSend
dasMessage
Objekt übergibt. DieMessageQueue
Klasse ist der Wrapper, der die Interaktion mit MSMQ verwaltet.Notiz
Die Syntax zum Festlegen des Pfads der privaten Warteschlange, die Sie in der Computerverwaltungskonsole erstellt haben. Private Warteschlangen haben die Form
machinename\Private$\queuename
. Lokale Hostcomputer werden mit einem Punkt bezeichnet (siehe .).MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay"); msgQ.Send(msg);
Der Code ist jetzt vorhanden, um eine Nachricht an MSMQ zu senden. .NET Framework serialisiert die Nachricht automatisch mithilfe eines
XMLMessageFormatter
Objekts. Dieses Objekt wird implizit erstellt, wenn Nachrichten gesendet werden.
Fügen Sie den Code in den folgenden Schritten zum
Click
Ereignis von button2 hinzu. Derbutton2_Click
Ereignishandler empfängt und verarbeitet die Zahlungsnachricht, die imbutton1
Ereignishandler gesendet wird.Die erste Codezeile entspricht der Codezeile, die sich im ersten Ereignishandler befindet:
MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
Erstellen Sie ein Array von Typen, die an die
XMLMessageFormatter
Klasse übergeben werden sollen.Notiz
Diese Klasse muss beim Empfangen von Nachrichten explizit erstellt werden. Vorzugsweise nimmt der Konstruktor der
XMLMessageFormatter
Klasse entweder ein String-Array mit Typnamen oder einType
Array von Typen an.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);
Die Typen geben an, wie
XMLMessageFormatter
die Nachricht deserialisieren soll.Nachrichten werden durch Aufrufen der
Receive
Methode empfangen. Greifen Sie auf dieBody
Eigenschaft zu, um den Nachrichteninhalt zu lesen. DieBody
Eigenschaft gibt ein Objekt zurück, daher muss das Objekt in den Zahlungstyp umgewandelt werden, um den Inhalt in einer verwendbaren Form abzurufen.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));
Erstellen Sie ein Meldungsfeld, um die Ergebnisse anzuzeigen:
MessageBox.Show(sb.ToString(), "Message Received!");
Vollständige Codeauflistung (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;
}
}
}
Notiz
Der Code sollte in Visual Studio 2005 geändert werden. Wenn Sie ein Windows Forms-Projekt erstellen, fügt Visual C# dem Projekt standardmäßig ein Formular hinzu. Dieses Formular heißt "Form1". Die beiden Dateien, die das Formular darstellen, werden Form1.cs und Form1.designer.cs benannt. Sie schreiben Ihren Code in Form1.cs. Die Designer.cs Datei ist der Ort, an dem der Windows Forms-Designer den Code schreibt, der alle Aktionen implementiert, die Sie durch Hinzufügen von Steuerelementen ausgeführt haben. Weitere Informationen zum Windows Forms-Designer in Visual C# 2005 finden Sie unter Creating a Project (Visual C#)
Überprüfen des Codes
Klicken Sie im Menü Debuggen auf Starten.
Geben Sie Werte in jedes Textfeld ein, und klicken Sie dann auf " Zahlung senden".
Kehren Sie zur Computerverwaltungskonsole zurück. Klicken Sie unter "Billpay" auf den Ordner "Warteschlangennachrichten" in "Private Warteschlangen", und vergewissern Sie sich dann, dass MSMQ eine Nachricht empfangen hat (gekennzeichnet durch ein Umschlagsymbol).
Klicken Sie mit der rechten Maustaste auf die Nachricht, klicken Sie auf Eigenschaften, und klicken Sie dann auf die Registerkarte "Inhalt". Sie bemerken die Nachricht zur Zahlung.
Notiz
Der Inhalt der Zahlungsnachricht wird als XML serialisiert.
Kehren Sie zur Windows-Rechnungszahlungsanwendung zurück, und klicken Sie dann auf die Schaltfläche "Zahlung verarbeiten". Es wird ein Meldungsfeld angezeigt, das den Empfang einer Nachricht bestätigt und die Nachricht anzeigt.
Problembehandlung
Der Mangel an privater Warteschlange ist in der Regel nur bei Windows 2000 Professional und Windows XP Professional ein Problem. Windows 2000 Server und Windows XP Server ermöglichen die Verwendung der öffentlichen Warteschlange.
Beim Übergeben der richtigen Argumente an
XMLMessageFormatter()
kann es schwierig sein. In diesem Beispiel werden Ausnahmen ausgelöst, wenn entweder das Objekt oder die Zahlungstypen nicht im Typarray enthalten sind, das an den Konstruktor übergeben wird.