Introduction
Talk of enterprise applications, things that come to your mind are transactions ,messaging etc. Talk of messaging, what strikes immediately is MSMQ which stands for Microsoft Message Queuing. MSMQ provides a great framework for applications that use messaging infrastructure.
In this article I will discuss very elementary concepts of MSMQ programming like creating a queue, writing a message to the queue and receiving from it etc.
Background
Let me take a couple of minutes here to explain what messaging is. Here, you have two applications: a sending application and a receiving application. A sending application prepares a message and puts it into a queue. A message can be any piece of information that the receiving application understands. The receiving application receives the message from the queue and processes it. One thing to note here is that the sender and the receiver are not tightly coupled and they can work without the other application being online.
Enter System.Messaging
To build a messaging application we need to create a queue first, have one application send messages to it and have another application receive those messages from it. So, in this article I shall focus mainly on these operations. Before doing that I would like to mention about the basic types of MSMQ queues: Private and Public. Public queues are those that are published in the active directory. So, applications running on different servers throughout the network can find and use public queues through the active directory. Private queues on the other hand are available locally on a particular machine and are not published in the active directory.
The System.Messaging
namespace provides a set of classes which can be used to work with MSMQ. In this article we will be mainly focusing on Message
and MessageQueue
classes. The MessageQueue
class provides all the necessary functionality to work with and manipulate MSMQ queues. It is like a wrapper around message queuing. The Message
class provides everything required to define and use an MSMQ message.
Creating a Queue
Queues can be created either programmatically or through the computer management snap-in. I presume MSMQ is installed on your system.
Programmatically
You can use the Create
shared method of the MessageQueue
class to create a queue. In the code snippet given below I am creating a private queue named MyNewQueue.
Try
Dim queueAsMessageQueue
queue = MessageQueue.Create(".\Private$\MyNewQueue")
Catch ex As MessageQueueException
End Try
Note the parameter I have passed to the the Create method. It is called the path of the queue. The single dot (.) in the path indicates the queue is created on the local machine. Since we are creating a private queue here, we need to include a Private$ in the path. If we are creating or accessing a public queue we can just use the MachineName\QueueName format in the path.
Through the computer management snap-in
- Open the computer management snap-in.
- Navigate to the [Message Queuing] node under the Services and Applications section.
- Right click on the [Private Queues] and in the context menu that appears select New -> Private Queue. Public queues can be created in a similar fashion.
Sending a simple message
We use the Send
method of the MessageQueue
object to post a message to the queue.
MyQueue.Send("<<Message>>", "<<Message Label>>")
One thing I would like to mention here is that the Send method takes an object as the first parameter to denote the message body. This can be a Message
object or any managed object. If the object is not of type Message,
then the object is serialized and stored in the message body.
Reading a message from the queue
There are two types of operations with respect to reading a message fom the Queue: Peeking and Receiving. When we receive a message from the queue, the message is removed from the queue. Peeking is similar to Receiving but here the message is not removed from the queue.
Dim msg As Message
msg = MyQueue.Receive()
MessageBox.Show(msg.Body)
There are many overloads of Receive and the one used above indefinitely blocks the caller till a message is available on the queue. On the other hand if you do not want to get blocked indefinitely then you can use the overload of Receive which takes a TimeSpan
argument and this throws an exception if a message is not received within that time span. Here is a call to receive which times out after 1000 ticks (1 second).
msg = MyQueue.Receive(New TimeSpan(1000))
We have seen that Peek and Receive operations are synchronous in nature. However there exists a method where we can do these operations asynchronously. For this, we can use the BeginPeek
and EndPeek
or BeginReceive
or EndReceive
respectively.
Deleting a Queue
We can use the Delete
shared method of the MessageQueue
object to delete a queue from the system.
MyQueue.Delete(".\Private$\MyNewQueue")
You can also delete a queue from the computer management console. Right click on the queue you wish to delete and select Delete from the context menu.
Other simple queue operations
Enlisted below are some other simple operations on a queue which you might be interested in.
Purge |
Deletes all the messages contained in the queue. |
GetAllMessages |
Returns all the messages that are in the queue. |
GetPrivateQueuesByMachine |
Retrieves all the private queues on the specified computer. |
Exists |
Determines whether a Message Queuing queue at the specified path exists. |
GetMessageEnumerator |
Creates an enumerator object for all the messages in the queue. |
Formatter |
Gets or sets the formatter used to serialize an object into or deserialize an object from the body of a message read from or written to the queue. |
A VS.NET Tip
You might have noticed that we have used a lot of the MessageQueue
objects in the samples. VS.NET makes development easier by providing objects in the toolbox which we can drag and drop to the designer surface. We can use the property sheet to initialize properties and then use the object straight away in our code.
About the Source
Included with this article is a VB.NET windows application project which has all the simple operations mentioned above implemented. Here's how it looks.
Towards the left of the screen in a treeview control enlisting all the private queues in the system. Messages are also listed under the respective queue nodes in the tree. The operations possible with this app are:
- Create a new private queue.
- Send a new message to the queue
- Delete (Receive) the top message from the queue.
- Delete a private queue.
Please excuse me if you find bugs in the project :)
Conclusion
In this article and in the VB.NET project that I have submitted, I have used only Private Queues. Also, I have not used transactional messaging. Please note the working with Public queues is almost identical but for some small changes in Path semantics. So, everything I have explained with respect to private queues will definitely hold good for public queues as well.
I will be doing an injustice to MSMQ if I finish off everything in a single article. In this article we saw the very basics of MSMQ. In the forthcoming article we shall see some more advanced concepts like Transactional messaging, serializing and deserializing messages, asynchronous operations etc.