C# Programming > Miscellaneous

Using MS-Queue in C#

 

Hearing the word "MS-Queue" for the first time might remind you of a queue data structure (like the one found in the System.Collections namespace). Although the concept is pretty close, MS-Queue is something entirely different.

The MS-Queue is a Windows component that offers an interesting mechanism to facilitate the exchange of data between software applications in the same computer or network (i.e. different sessions). The MS-Queue works as a FIFO queue at the operating system level. The data exchanged through the queue can be anything: text, images, serialized objects, etc.

Why would we need this? Picture a scenario where a system receives customer orders from an outside source at a faster rate than the system can process them. The MS-Queue would be ideal in this case since it would receive and store the orders while the application in charge of processing them simply requests the next order from the MS-Queue.

In this case, one application (i.e. service) would be in charge of receiving the orders and putting them in a Queue. A second application would be in charge of taking them out of the Queue and processing them.

Although the MS-Queue is part of most Windows operating systems components, it is usually not installed as part of the default installation. So before continuing you might have to install it.

Once installed, the developer can take advantage of it. Here is a screen shot that depicts the idea of installing the component by enabling it in the Windows component installation screen (It is similar for Windows XP, Windows Vista, or Windows 7, Windows servers, for Windows 2000 and NT is an option and need separate installation).

Windows MS-Queue  

 

Now, through the Computer Management (Control Panel -> Administrative Tools) the queue can be observed. The following screen shot shows what you might see:

MS-Queue Viewer

There are Public and Private Queues. It is common for developers to use the private queues folder. The developer has the option to create a Queue manually or programmatically. The created Queue will have a name that will be used in the code.

There are alternative programs for Queue viewers that can provide more information than the Computer Management tool. For example one tool is the MSMQ Studio by Geek Project (http://www.geekproject.com), It is free and works really well.

It is up to you whether you want these more advanced tools. For the purposes of this article, the default Windows tool will be sufficient.

 

MS-Queues in .NET Applications

We are almost ready to use the MS-Queue in our .NET applications. One last step is to allow the C# program to access the System.Messaging namespace. This is not a default reference! You have to go under Project > Add Reference and find it under the .NET tab. Once you have that, you are ready to use the MS-Queue in your C# applications.

Within the code, the way to reference a queue will be through its name and folder location in the Message Queue (this is known as the Queue path), for example,

string myQueuePath = @".\private$\myQueue";

It is simple to create a Queue, the example is as follows:

public static void CreateQueue(string queuePath)
{
   try
   {
      if (!MessageQueue.Exists(queuePath))
      {
          MessageQueue.Create(queuePath);
      }
      else
      {
          Console.WriteLine(queuePath + " already exists.");
      }
    }
    catch (MessageQueueException e)
    {
       Console.WriteLine(e.Message);
    }
}

Once the queue is created, the next step is to put data by means of a message. The following example is a method that will put a new message (an image in this case) into the queue:

public void SendMessage(string _queue, string _ImagePath)
{
   try
   {
      // prepare image for the Queue
      Image myImage = Bitmap.FromFile(_ImagePath);
 
      // Connect to a queue on the local computer.
      MessageQueue myQueue = new MessageQueue(_queue);
                
      // Prepare message 
      Message myMessage = new Message();
      myMessage.Body = myImage;
      myMessage.Formatter = new BinaryMessageFormatter();
               
      // Send the message into the queue.
      myQueue.Send(myMessage);
   }
   catch (ArgumentException e)
   {
      Console.WriteLine(e.Message);
   }

   return;
}

The data can be retrieved by indicating the Queue itself what type of message is coming out. The following code depicts the idea:

public void ReceiveMessage(string _Queue, string _Image)
{
   try
   {
       // Connect to the a queue on the local computer.
       MessageQueue myQueue = new MessageQueue(_Queue);

       // Set the formatter to indicate body contains 
       // an binary object
       myQueue.Formatter = new BinaryMessageFormatter();

       // Receive and format the message. 
       Message myMessage = myQueue.Receive();
       Bitmap myImage = (Bitmap)myMessage.Body;

       // Save received image
       myImage.Save(_Image, System.Drawing.Imaging.ImageFormat.Bmp);
    }
    catch (MessageQueueException)
    {
          // Handle Message Queuing exceptions.
    }
    catch (InvalidOperationException e)
    {
        // Handle invalid serialization format.
         Console.WriteLine(e.Message);
    }
    catch (IOException e)
    {
        // Handle file access exceptions.
    }
    // Catch other exceptions as necessary.
       
    return;
}

The developer can assign to the message Body the object to store, and the message Formatter will have the way to serialize it before storing the message into the Queue.  The serialized contents are found in the BodyStream property.

An alternative path can be done by assigning to the message BodyStream a serialized object.

Now, one class is worth looking is the MessageQueueTransaction class, which offers like any other transaction processes, an all or nothing data storage.

For example, consider the case that you want to store an object and implements a particular interface:

private static void SendToOutputQueue(IMyMessage _MyMsg)
{
    MemoryStream ms = null;

    try
    {
        ms = new MemoryStream();
        XmlSerializer xs = new XmlSerializer(typeof(IMyMessage));
        xs.Serialize(ms, _MyMsg);

        Message outMsg = new Message();
        outMsg.Formatter = new ActiveXMessageFormatter();
        outMsg.Label = "Object ID 123456";
        outMsg.BodyStream = ms;

        //handle resources lifespan 
        using (MessageQueueTransaction trans = new MessageQueueTransaction())
        {
            trans.Begin();
            //send message to output queue
            string outPath = @".\private$\myQueue";
            MessageQueue outQueue = new MessageQueue(outPath);

            outQueue.Send(outMsg, trans);
            trans.Commit();
        }

        outputMsg.Dispose();
    }
    catch (Exception ex)
    {
        //handle exceptions ot throw; 
    }
    finally
    {
        if (ms != null)
        {
            ms.Close();
            ms.Dispose();
        }
    }
}  

The MS-Queue offers many classes and functionality to integrate to different application needs. It is a great resource and it is worth to stop and look into some of the available information and add it to the tools for a next great project.  

For more information refer to the MSDN page:
http://msdn.microsoft.com/en-us/library/system.messaging.messagequeue.aspx

Back to C# Article List