Example #1
0
        /// <summary>
        /// Asks MSMQ to attempt to deliver a message.
        /// To ensure the message reached the queue you need to check acknowledgement messages sent to the <see cref="Message.AdministrationQueue"/>
        /// </summary>
        /// <param name="message">The message to try to send</param>
        /// <param name="transaction">can be NULL for no transaction, a <see cref="QueueTransaction"/>, <see cref="QueueTransaction.Single"/>, or <see cref="QueueTransaction.Dtc"/>.</param>
        public void Write(Message message, QueueTransaction transaction = null)
        {
            Contract.Requires(message != null);

            message.Props.PrepareToSend();
            var props = message.Props.Allocate();

            try
            {
                int    res;
                IntPtr txnHandle;
                if (transaction.TryGetHandle(out txnHandle))
                {
                    res = Native.SendMessage(_handle, props, txnHandle);
                }
                else
                {
                    res = Native.SendMessage(_handle, props, transaction.InternalTransaction);
                }

                if (Native.IsError(res))
                {
                    throw new QueueException(res);
                }
            }
            finally
            {
                message.Props.Free();
            }
        }
Example #2
0
        /// <summary>Move the message specified by <paramref name="lookupId"/> from <paramref name="sourceQueue"/> to the <paramref name="targetQueue"/>.</summary>
        /// <remarks>
        /// Moving message is 10 to 100 times faster than sending the message to another queue.
        /// Within a transaction you cannot receive a message that you moved to a subqueue.
        /// </remarks>
        public static void MoveMessage(QueueReader sourceQueue, SubQueue targetQueue, long lookupId, QueueTransaction transaction = null)
        {
            Contract.Requires(sourceQueue != null);
            Contract.Requires(targetQueue != null);

            if (sourceQueue.IsClosed)
            {
                throw new ObjectDisposedException(nameof(sourceQueue));
            }
            if (targetQueue.IsClosed)
            {
                throw new ObjectDisposedException(nameof(targetQueue));
            }

            int    res;
            IntPtr txnHandle;

            if (transaction.TryGetHandle(out txnHandle))
            {
                res = Native.MoveMessage(sourceQueue._handle, targetQueue.MoveHandle, lookupId, txnHandle);
            }
            else
            {
                res = Native.MoveMessage(sourceQueue._handle, targetQueue.MoveHandle, lookupId, transaction.InternalTransaction);
            }

            if (Native.IsError(res))
            {
                throw new QueueException(res);
            }
        }
Example #3
0
        /// <summary>Tries to peek (or receive) a message using the queue-specific <paramref name="lookupId"/></summary>
        /// <remarks>Within a transaction you cannot receive a message that you moved to a subqueue within the same transaction</remarks>
        /// <param name="properties">The properties to read</param>
        /// <param name="lookupId">The <see cref="Message.LookupId"/> of the message to read</param>
        /// <param name="action">Receive or peek a message?</param>
        /// <param name="timeout">The time allowed, defaults to infinite.  Use <see cref="TimeSpan.Zero"/> to return without waiting</param>
        /// <param name="transaction">can be NULL for no transaction, a <see cref="QueueTransaction"/>, <see cref="QueueTransaction.Single"/>, or <see cref="QueueTransaction.Dtc"/>.</param>
        /// <returns>The message, or NULL if the message was not found or the receive times out</returns>
        public unsafe Message Lookup(Properties properties, long lookupId, LookupAction action = LookupAction.ReceiveCurrent, TimeSpan?timeout = null, QueueTransaction transaction = null)
        {
            if (IsClosed)
            {
                throw new ObjectDisposedException(nameof(Queue));
            }

            uint timeoutMS = TimeoutInMs(timeout);
            var  msg       = new Message();
            int  res;

            msg.Props.SetForRead(properties);
            for (;;) // loop because we might need to adjust memory size
            {
                var props = msg.Props.Allocate();
                try
                {
                    IntPtr txnHandle;
                    if (transaction.TryGetHandle(out txnHandle))
                    {
                        res = Native.ReceiveMessageByLookupId(_handle, lookupId, action, props, null, null, txnHandle);
                    }
                    else
                    {
                        res = Native.ReceiveMessageByLookupId(_handle, lookupId, action, props, null, null, transaction.InternalTransaction);
                    }
                }
                finally
                {
                    msg.Props.Free();
                }

                if ((ErrorCode)res == ErrorCode.IOTimeout || (ErrorCode)res == ErrorCode.MessageNotFound)
                {
                    return(null);
                }

                if (Native.NotEnoughMemory(res))
                {
                    msg.Props.IncreaseBufferSize();
                    continue; // try again
                }

                if (Native.IsError(res))
                {
                    throw new QueueException(res);
                }

                msg.Props.ResizeBody();
                return(msg);
            }
        }