OdeToCode IC Logo

The Mysteries Of System.Messaging

Sunday, June 11, 2006

The majority of the .NET base class library feels clean and intuitive. Every so often though, you come across some oddballs. For instance…

Given a MessageQueue object named queue, what does the following code produce at compile time?

foreach (Message message in queue)
{
    
// ...
}

The code results in a warning:

'System.Messaging.MessageQueue.GetEnumerator()' is obsolete: 'This method returns a MessageEnumerator that implements RemoveCurrent family of methods incorrectly. Please use GetMessageEnumerator2 instead.'

Wow! Deprecating the GetEnumerator method is serious business. Using foreach is now out of the question.

The AcknowledgeTypes enum baffles me. There seems to be a lack of symmetry in the names. If we want an acknowledgment that a message has reached it's queue, we use the "PositiveArrival" flag, but if want an acknowledgment when a message doesn't arrive we use the "NotAcknowledgeReachQueue" flag. Arrival and reach are easy to distinguish from a receive, which means something successfully pulled the message from the queue, but what if we want to request an acknowledgement if something doesn't receive our message? There is the NotAcknowledgeReceive flag, which combines the NegativeReceive and the NotAcknowledgeReachQueue. Do you acknowledge all this? Negative! 

Finally, there seems to be too much of a good thing going on with asynch operations. I can call BeginReceive on a queue to start a receive, and pass a callback method, or I can subscribed to the ReceiveCompleted event and then call BeginReceive. In the ReceiveCompleted event handler I can call EndReceive manually (which feels good, because Begin and End calls should match), or use the Message property of the incoming RecieveCompletedEventArgs parameter and fetch the Message property (which calls EndReceive under the covers).

Choices, choices.