Usare Visual C# per scrivere e leggere da Accodamento messaggi Microsoft

Questo articolo descrive come scrivere e leggere da Accodamento messaggi Microsoft (MSMQ) in Visual C#.

Versione originale del prodotto: Accodamento messaggi Microsoft
Numero KB originale: 815811

In questa attività

Riepilogo

In questo articolo vengono trattati gli argomenti seguenti:

  • Come creare un messaggio e inviarlo a MSMQ in un'applicazione Windows.
  • Come leggere da una coda privata e deserializzare il contenuto del messaggio per la visualizzazione.

Requisiti

Gli elementi seguenti descrivono l'hardware, il software, l'infrastruttura di rete, le competenze e le conoscenze consigliate e i Service Pack necessari:

  • Uno dei sistemi operativi seguenti con MSMQ installato (è incluso come opzione nei quattro sistemi operativi): Windows 2000 Professional (o Server) o Windows XP Professional (o Server).

Questo articolo presuppone anche che si abbia familiarità con quanto segue:

  • MSMQ
  • Uso degli strumenti dal prompt dei comandi

torna in alto

Scrivere e leggere da MSMQ

Lo System.Messaging spazio dei nomi in .NET Framework include le classi da cui è necessario leggere e scrivere in MSMQ. Per creare una piccola applicazione Windows che simula un sistema di pagamento delle fatture online, seguire questa procedura:

  1. Aprire Visual Studio .NET o Visual Studio 2005.

  2. Creare una nuova applicazione Windows in Visual C# e quindi denominarla MSMQ.

  3. Per visualizzare Esplora soluzioni se non viene visualizzato, premere CTRL+ALT+L. In Esplora soluzioni fare clic con il pulsante destro del mouse su Riferimenti e quindi scegliere Aggiungi riferimento.

  4. Nella scheda .NET selezionare il file System.Messaging.dll nell'elenco dei file .dll . Fare clic su Seleziona e quindi su OK.

    Nota

    In Visual Studio 2005 fare clic sul file System.Messaging.dll nell'elenco di DLL e quindi fare clic su OK.

  5. Form1.cs è aperto nella visualizzazione Struttura. Se non è aperto, fare doppio clic su Form1.cs in Esplora soluzioni.

  6. Premere CTRL+ALT+X per aprire la casella degli strumenti. Nella casella degli strumenti fare clic sulla scheda Windows Forms.

  7. Dalla casella degli strumenti trascinare quanto segue al centro di Form1:

    • Quattro righe ciascuna di un'etichetta e una casella di testo (posizionate a destra di ogni etichetta).
    • Nelle etichette e nelle caselle di testo trascinare due controlli Button in Form1.
  8. Fare clic con il pulsante destro del mouse sui controlli, scegliere Proprietà e quindi impostare la proprietà Text per le etichette su quanto segue (nell'ordine):

    • Pagamento a:
    • Il tuo nome:
    • Quantità:
    • Scadenza:
  9. Nella finestra di dialogo Proprietà impostare la proprietà Testo di button1 su Invia pagamento e impostare la proprietà Testo di button2 su Elabora pagamento.

  10. Questa applicazione funziona con una coda privata che è necessario creare nella console di gestione computer. A tal fine, attenersi alla seguente procedura:

    1. Sul desktop fare clic con il pulsante destro del mouse su Risorse del computer e quindi scegliere Gestisci.
    2. Espandere il nodo Servizi e applicazioni per trovare MSMQ.

    Nota

    Se MSMQ non viene trovato, non è installato.

  11. Espandere Accodamento messaggi, fare clic con il pulsante destro del mouse su Code private, scegliere Nuovo e quindi fare clic su Coda privata.

  12. Nella casella Nome coda digitare billpay e quindi fare clic su OK.

    Nota

    Non selezionare la casella di controllo Transazionale . Lasciare aperta la console di Gestione computer perché si torna a tale console in un secondo momento per visualizzare i messaggi.

  13. All'inizio del codice in Form1 aggiungere due USING istruzioni prima della dichiarazione di classe per includere le classi aggiuntive che risiedono nello System.Messaging spazio dei nomi e negli System.Text spazi dei nomi. Lo System.Text spazio dei nomi è destinato all'uso della StringBuilder classe , una nuova classe .NET Framework che è preferibile usare quando si concatenano stringhe.

    using System.Messaging;
    using System.Text;
    
  14. Creare una struttura che contiene variabili per contenere i dati che definiscono un pagamento. Per creare la struttura, aggiungere il codice seguente dopo la procedura Main:

    public struct Payment
    {
        public string Payor,Payee;
        public int Amount;
        public string DueDate;
    }
    
  15. Aggiungere il codice nei passaggi seguenti all'evento Click di button1.

    1. Impostare le proprietà della struttura sui valori degli elementi del modulo come indicato di seguito:

      Payment myPayment;
      myPayment.Payor = textBox1.Text;
      myPayment.Payee = textBox2.Text;
      myPayment.Amount = Convert.ToInt32(textBox3.Text);
      myPayment.DueDate = textBox4.Text;
      
    2. Creare un'istanza della Message classe e quindi impostare la Body proprietà sulla payment struttura:

      System.Messaging.Message msg = new System.Messaging.Message();
      msg.Body=myPayment;
      
    3. Per inviare un messaggio a MSMQ, creare un'istanza della MessageQueue classe e chiamare il Send metodo che passa nell'oggetto Message . La MessageQueue classe è il wrapper che gestisce l'interazione con MSMQ.

      Nota

      Sintassi per l'impostazione del percorso della coda privata creata nella console di Gestione computer. Le code private hanno il formato machinename\Private$\queuename. Ai computer host locali viene fatto riferimento con un punto o un punto (mostrato come .).

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

      Il codice esiste ora per inviare un messaggio a MSMQ. .NET Framework serializza automaticamente il messaggio usando un XMLMessageFormatter oggetto . Questo oggetto viene creato in modo implicito quando vengono inviati messaggi.

  16. Aggiungere il codice nei passaggi seguenti all'evento Click di button2. Il button2_Click gestore eventi riceve ed elabora il messaggio di pagamento inviato nel button1 gestore eventi.

    1. La prima riga di codice è la stessa della riga di codice presente nel primo gestore eventi:

      MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
      
    2. Creare una matrice di tipi da passare alla XMLMessageFormatter classe .

      Nota

      Questa classe deve essere creata in modo esplicito durante la ricezione di messaggi. Il costruttore della XMLMessageFormatter classe accetta una matrice di stringhe di nomi di tipo o, preferibilmente, una Type matrice di tipi:

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

      Questi tipi indicano come XMLMessageFormatter deserializzare il messaggio.

    3. I messaggi vengono ricevuti chiamando il Receive metodo . Accedere alla Body proprietà per leggere il contenuto del messaggio. La Body proprietà restituisce un oggetto, pertanto è necessario eseguire il cast dell'oggetto al tipo di pagamento per recuperare il contenuto in un formato utilizzabile:

      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. Creare una finestra di messaggio per visualizzare i risultati:

      MessageBox.Show(sb.ToString(), "Message Received!");
      

torna in alto

Elenco di codice completo (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;
        }
    }
}

Nota

Il codice deve essere modificato in Visual Studio 2005. Quando si crea un progetto Windows Forms, Visual C# aggiunge una maschera al progetto per impostazione predefinita. Questo modulo è denominato Form1. I due file che rappresentano il modulo sono denominati Form1.cs e Form1.designer.cs. Si scrive il codice in Form1.cs. Il file Designer.cs è il percorso in cui il Windows Forms Designer scrive il codice che implementa tutte le azioni eseguite aggiungendo controlli. Per altre informazioni sulla Windows Forms Designer in Visual C# 2005, vedere Creazione di un progetto (Visual C#)

torna in alto

Verificare il codice

  1. Scegliere Avvia dal menu Debug.

  2. Digitare i valori in ogni casella di testo e quindi fare clic su Invia pagamento.

  3. Tornare alla console di Gestione computer. Fare clic sulla cartella Messaggi di coda in Code private con pagamento in conto e quindi verificare che MSMQ ha ricevuto un messaggio (indicato da un'icona della busta).

  4. Fare clic con il pulsante destro del mouse sul messaggio, scegliere Proprietà e quindi fare clic sulla scheda Corpo . Si nota il messaggio di pagamento.

    Nota

    Il contenuto del messaggio di pagamento viene serializzato come XML.

  5. Tornare all'applicazione Windows per il pagamento della fattura e quindi fare clic sul pulsante Elabora pagamento . Viene visualizzata una finestra di messaggio che conferma la ricezione di un messaggio e visualizza il messaggio.

torna in alto

Risoluzione dei problemi

  • La mancanza di una coda privata è in genere un problema solo in Windows 2000 Professional e Windows XP Professional. Windows 2000 Server e Windows XP Server consentono l'uso della coda pubblica.

  • Passare gli argomenti corretti a XMLMessageFormatter() può essere complicato. In questo esempio vengono generate eccezioni se l'oggetto o i tipi di pagamento non sono inclusi nella matrice Type passata al costruttore.

torna in alto