I have a method that reads a list of messages from a message queue. The signature is:
IList<TMsg> Read<TMsg>(MessageQueue queue, int timeout, MessageQueueTransaction tx);
The basic functionality is that it will reads as many messages as it can from the queue, within the timeout, using the given transaction. The problem I’m having is deciding on how best to enforce the timeout. I have two working versions at the moment. These are:
- Using BeginPeek with a timeout. If it succeeds, the message is removed with a transactional Receive call. The timeout for BeginPeek is recalculated after each call, based on the time the Read began, and the current time.
- Using Receive with the timeout value, and catching the exception when the timeout expires.
The problem with the first approach is that it requires the queue to be read in DenySharedReceive mode, otherwise you can’t guarantee the message will still be there between the Peek and Receive. The problem with the second method is that an exception needs to be thrown and handled (albeit, internally and transparently) which is probably not a great design since each call will always end in an exception which goes against the idea of throwing exceptions only in exceptional circumstances.
Does anyone have any other suggestions how I might achieve this, or comments on these two techniques and my concerns?
After a bit of investigation, hatchet’s comment is the closest to the ‘answer’, at least as far as .NET is concerned. The wrapped native methods provide a return value (rather than error value) for ‘TIMEOUT’, but this is considered an exception by .NET and re-wrapping the native code is just not worth it. I tried. :p