Come lavorare con MSMQ in C #

MSMQ (Microsoft Message Queuing) è una coda di messaggi disponibile per impostazione predefinita come parte di Windows. Un modo affidabile per inviare e ricevere messaggi attraverso i sistemi di computer, MSMQ fornisce una coda che è scalabile, thread-safe, semplice e comoda da usare, fornendo allo stesso tempo l'opportunità di mantenere i messaggi all'interno del database di Windows. L'MSDN afferma: "La tecnologia di Accodamento messaggi (MSMQ) consente alle applicazioni in esecuzione in momenti diversi di comunicare tra reti eterogenee e sistemi che potrebbero essere temporaneamente offline. Le applicazioni inviano messaggi alle code e leggono i messaggi dalle code."

In genere, si hanno due applicazioni distinte quando si lavora con MSMQ: il mittente e il destinatario. Quando i messaggi vengono inviati dal mittente, ovvero l'applicazione di invio, l'applicazione di ricezione non deve essere in stato di esecuzione: i messaggi vengono effettivamente archiviati in una coda mantenuta dal sistema operativo host e vengono rimossi dalla coda ogni volta che vengono sono necessari all'applicazione ricevente.

Creazione di una coda

Puoi attivare MSMQ nel tuo sistema tramite l'opzione "Attiva o disattiva le funzionalità di Windows" dal pannello di controllo. Una volta che MSMQ è stato installato nel sistema, creare una coda è semplice. Basta andare su "Risorse del computer", fare clic con il tasto destro e selezionare Gestisci. Nella finestra "Gestione computer" è possibile creare una nuova coda dal nodo "Accodamento messaggi". È inoltre possibile creare una coda a livello di codice.

Programmazione di MSMQ in C #

Per lavorare con MSMQ, è necessario includere lo spazio dei nomi System.Messaging. Per creare una coda a livello di codice, è necessario sfruttare il metodo Create della classe MessageQueue. Lo snippet di codice seguente lo illustra.

MessageQueue.Create(@".\Private$\");

Per creare una coda e inviarle un messaggio, puoi utilizzare il seguente frammento di codice.

MessageQueue.Create(@".\Private$\");              

messageQueue = new MessageQueue(@".\Private$\");

messageQueue.Label = "This is a test queue.";

messageQueue.Send("This is a test message.", "");

Supponiamo ora di voler controllare se la coda esiste e, in caso affermativo, inviare un messaggio ad essa. Se la coda non esiste, potresti crearne una nuova e inviarle un messaggio. Questo è esattamente ciò che fa per te il seguente listato di codice.

static void Main(string[] args)

        {

            MessageQueue messageQueue = null;

            string description = "This is a test queue.";

            string message = "This is a test message.";

            string path = @".\Private$\";

            try

            {

                if (MessageQueue.Exists(path))

                {

                    messageQueue = new MessageQueue(path);

                    messageQueue.Label = description;

                }

                else

                {

                    MessageQueue.Create(path);

                    messageQueue = new MessageQueue(path);

                    messageQueue.Label = description;

                }

                messageQueue.Send(message);

            }

            catch

            {

                throw;

            }

finally

{

           messageQueue.Dispose();

}

      }

Il listato di codice seguente illustra come elaborare i messaggi archiviati in una coda di messaggi utilizzando C #.

private static List ReadQueue(string path)

        {

            List lstMessages = new List();

            using (MessageQueue messageQueue = new MessageQueue(path))

            {

                System.Messaging.Message[] messages = messageQueue.GetAllMessages();

                foreach (System.Messaging.Message message in messages)

                {

                    message.Formatter = new XmlMessageFormatter(

                    new String[] { "System.String, mscorlib" });

                    string msg = message.Body.ToString();

                    lstMessages.Add(msg);

                }

            }

            return lstMessages;

        }

Successivamente, puoi richiamare il metodo ReadQueue per recuperare i messaggi archiviati nella coda dei messaggi come mostrato nello snippet di codice di seguito.

string path = @".\Private$\";

List lstMessages = ReadQueue(path);

È inoltre possibile memorizzare oggetti nella coda dei messaggi. Ad esempio, supponiamo di dover memorizzare un messaggio di log nella coda. Il messaggio di registro viene archiviato in un'istanza della classe LogMessage che contiene le proprietà necessarie relative ai dettagli del messaggio di registro. Ecco come apparirebbe la classe LogMessage: l'ho resa semplice con solo due proprietà.

public class LogMessage

    {

        public string MessageText { get; set; }

        public DateTime MessageTime { get; set; }

    }

È necessario modificare la classe LogMessage per incorporare altre proprietà necessarie, ad esempio, gravità del messaggio, ecc. Il metodo seguente illustra come memorizzare un'istanza della classe LogMessage nella coda dei messaggi.

private static void SendMessage(string queueName, LogMessage msg)

        {

            MessageQueue messageQueue = null;

            if (!MessageQueue.Exists(queueName))

                messageQueue = MessageQueue.Create(queueName);

            else

                messageQueue = new MessageQueue(queueName);          

            try

            {

                messageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(LogMessage) });

                messageQueue.Send(msg);

            }

            catch

            {

                //Write code here to do the necessary error handling.

            }

            finally

            {

                messageQueue.Close();

            }          

        }

Il frammento di codice seguente illustra come creare un'istanza della classe LogMessage, popolarla con i dati e quindi richiamare il metodo SendMessage per archiviare l'istanza creata nella coda dei messaggi.

LogMessage msg = new LogMessage()

            {

                MessageText = "This is a test message.",

                MessageTime = DateTime.Now

            };

SendMessage(@".\Private$\Log", msg);

Il seguente elenco di codice illustra come leggere l'istanza di LogMessage archiviata nella coda dei messaggi.

private static LogMessage ReceiveMessage(string queueName)

        {

            if (!MessageQueue.Exists(queueName))

                return null;

            MessageQueue messageQueue = new MessageQueue(queueName);

            LogMessage logMessage = null;

            try

            {

                messageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(LogMessage) });

                logMessage = (LogMessage)messageQueue.Receive().Body;

            }

            catch { }

            finally

            {

                messageQueue.Close();

            }

            return logMessage;

        }