dcsimg
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

MSMQ for .NET Developers (Part 1) : Page 6

MSMQ provides robust and easy-to-use messaging capabilities that let you send and receive messages between applications running on one machine, different machines, and even across the Internet, both synchronously and asynchronously. Unfortunately, MSMQ is notoriously underused. Find out how to get started with MSMQ and what you can do with it.


advertisement
Messaging with MSMQ
The System.Messaging namespace provides a concise way to send a simple message to a queue. Simply open the queue, and send a simple string-based message. This option does not support modifying the default attributes of the message before sending it. The code below demonstrates this functionality. The Try/Catch block was added for completeness.

   Private Sub SendMessage()
      Dim myQueue As MessageQueue
      Try
         myQueue = New MessageQueue(".\private$\DevXTestQueue")
         myQueue.Send("This is a sample message body")
      Catch ex As Exception
         MessageBox.Show("Exception was thrown: " & _
            ex.Source & ": " & ex.Message)
      End Try
   End Sub
To send a more complex message, for example when you need to modify the default attributes of a message before sending it, such as setting the CorrelationId, the ResponseQueue property, or making other modifications, you must first create a message object, set the properties, and then send the message, for example:

   Private Sub SendMessage(Byval MessageBody as String)
      Dim RequestQueue As System.Messaging.MessageQueue
      Dim ResponseQueue As System.Messaging.MessageQueue
      Dim RequestMessage As System.Messaging.Message
   
      ' open the request and receive queues
      RequestQueue = GetRequestQueue()
      ResponseQueue = GetResponseQueue()
   
      ' create the message and set properties
      RequestMessage = New Message
      RequestMessage.Body = MessageBody
      RequestMessage.ResponseQueue = ResponseQueue
      RequestMessage.TimeToBeReceived = New TimeSpan(0, 1, 0)
      MessageId = RequestMessage.Id()
   
      ' send the message
      RequestQueue.Send(RequestMessage)
   End Sub
Receiving a Single Message
Until now, the discussion has centered on sending messages, but it's time to look at the process of receiving messages. To receive a message, you create a queue reference for the queue from which you expect to receive a message, and then call the MSMQ Receive method, specifying the amount of time to wait for a message to arrive in the queue, expressed as a TimeSpan object. The TimeSpan object has several overloaded constructors, but they are all self-explanatory. See the code sample below.

   Private Sub ReceiveMessage()
      Dim myQueue As MessageQueue
      Dim myMsg As System.Messaging.Message
      Try
         ' create a queue reference
         myQueue = New MessageQueue(".\private$\DevXTestQueue")
   
         ' set the formatter for the received message
         myQueue.Formatter = New XmlMessageFormatter( _
            New Type() {GetType(System.String)})
   
         ' retrieve the message from the queue, waiting for no 
         ' longer than X seconds
         myMsg = myQueue.Receive(New TimeSpan(0, 0, 5))
   
         ' display the message
         If Not IsNothing(myMsg) Then
            MessageBox.Show("Message Received: " & CStr(myMsg.Body))
         End If
   
      ' handle any exceptions that were raised
      Catch exQueue As MessageQueueException
         MessageBox.Show("The receive timeout expired " & _
            "before a message was received.")
      Catch ex As Exception
         MessageBox.Show("Generic Exception was thrown: " & _
            ex.Source & ": " & ex.Message)
      End Try
   End Sub
Receiving Messages Asynchronously
Receiving a single message is a simple process, but the Receive method shown above causes the thread to block every time it's called. Depending on how often you call the Receive method, and on how long it waits for a message to arrive, your application could be waiting (blocked) for long periods of time. This could cause serious performance problems for your application.

A better approach to retrieving messages, especially when the application 'listens' to the queue for all incoming messages, is to retrieve the messages asynchronously. To retrieve the messages asynchronously, MSMQ provides a BeginReceive method that doesn't block when called. The most efficient way to receive new-message notifications is to set a callback delegate that MSMQ can call when new messages arrive. If you would like MSMQ to begin looking for another message, you must instruct MSMQ to begin another asynchronous receive operation. In the code below, the MSMQ_ReceiveCompleted procedure receives the message and instructs MSMQ to begin another asynchronous receive.

   Private Sub StartListening()
      Dim myReceiveQueue As MessageQueue
      Try
         ' open the receive queue
         myReceiveQueue = New _
            MessageQueue(".\private$\DevXTestQueue")
   
         ' set the receive queue formatter
         myReceiveQueue.Formatter = New XmlMessageFormatter( _
            New Type() {GetType(System.String)})
   
         ' add a handler for the ReceiveCompleted event and 
         ' call BeginReceive
         AddHandler myReceiveQueue.ReceiveCompleted, _
            AddressOf MSMQ_ReceiveCompleted
         myReceiveQueue.BeginReceive()
   
      Catch ex As Exception
         MessageBox.Show("Generic Exception was thrown: " _
            & ex.Source & ": " & ex.Message)
      End Try
   End Sub
   
   Public Sub MSMQ_ReceiveCompleted( _
      ByVal p_source As Object, _
      ByVal p_objAsyncResult As ReceiveCompletedEventArgs)
      Dim myMessage As Message
      Dim myMessageQueue As MessageQueue
   
      ' cast the source parm to a MessageQueue object
      myMessageQueue = CType(p_source, MessageQueue)
   
      ' calling EndReceive will return the message that was received
      myMessage = myReceiveQueue.EndReceive( _
         p_objAsyncResult.AsyncResult)
   
      ' do something useful with the message
      MessageBox.Show(CStr(myMessage.Body))
   
   End Sub
MSMQ provides an easy-to-use facility for exchanging messages between applications. It also provides a robust queuing framework, with many advanced capabilities that I did not have space to cover. In a later article, I will discuss more advanced features of MSMQ, and some ways to make it more robust.



Michael S. Jones is the Director of Systems Architecture for Passport Health Communications, Inc., a national healthcare technology provider connecting hospitals, physician clinics and outpatient centers with payer and patient information to facilitate and improve their revenue cycle process. Michael, his wife, and three children live in Franklin, Tennessee where he spends his spare time reading and enjoying time with his family outdoors. .
Thanks for your registration, follow us on our social networks to keep up-to-date