The introduction to this serious of Microsoft Message Queuing (MSMQ) posts is here. This time around, I’d like to show you how to read (or receive, dequeue, or pick) a message from a local queue.
By default, the first message read from the queue is the message with the highest priority followed by the time received (first in, first out – FIFO). You have the ability to override this behavior when required.
The following is a simple form of reading a message from a queue.
Dim _queue As MessageQueue
Dim _messageBodyContents As String
Try
_queue = New MessageQueue("QueueName")
Dim _messageFormatter As XmlMessageFormatter = CType(mQueue.Formatter, XmlMessageFormatter)
_messageFormatter.TargetTypeNames = New String() {"System.String,mscorlib"}
_message = _queue.Peek(New TimeSpan(10000))
_messageBodyContents = CType(_message.Body, String)
' Perform business logic
_queue.Receive()
_message = _queue.ReceiveById(_message.Id)
Catch ex As MessageQueueException
If ex.MessageQueueErrorCode = MessageQueueErrorCode.IOTimeout Then
' Queue is empty
Else
' Handle the exception
End If
End Try
You must create an instance of an MSMQ MessageQueue to begin. In the above example, note that I first Peek the message. This allows me to get a copy of the message, perform the required business logic, and only then receive the message (ReceiveById). This allows be to be sure the necessary business logic has completed successfully before I delete the message from the queue (which is what receiving the message does). If the message or associated business logic is not critical, you can skip the Peek/ReceiveById and simply use the MessageQueue.Receive method.
The Peek and Receive methods are blocking calls. This may be acceptable for your needs. I prefer to use the optional parameter and set a timeout on this block. This thread is then free to perform other actions (and shut down if told to do so).
Queue Names
The name of the message queues can be a difficult concept to pick up. Things are pretty simple when reading local queues. It get’s a bit more complicated with remote queues (that is, queues that physically exist on a different machine). A local private queue name follows this format:
“.\private$\TestQueue”
A more verbose option is also fine:
“FormatName:DIRECT=OS:[ComputerName]\private$\TestQueue”
As is a TCP option which is really unnecessary when working locally but it will work just the same:
“FormatName:DIRECT=TCP:10.200.1.1\private$\TestQueue”
Queue Security
An item that frequently trips people up is forgetting to set security on an MSMQ message queue. By default, anyone can use MSMQ to send a message to a queue but NOT read from it. You can tailor the settings to meet your security requirements using the same Computer Management plug-in as is used to manage queues (or it can be done programatically). For a development sandbox, giving the Everyone group Full Control will get you going.
For more message queuing implementation details try these additional posts:
Leave a Reply