/// <summary> /// Uses a <see cref="QueueCursor"/> to look for messages with a matching <paramref name="correlationId"/> /// Returns the matching message or NULL if no matching message can be found with the allowed <paramref name="timeout"/>. /// </summary> public static async Task <Message> ReadByCorrelationIdAsync(this QueueReader queue, MessageId correlationId, Properties properties = Properties.All, TimeSpan?timeout = null, QueueTransaction transaction = null) { timeout = timeout ?? QueueReader.Infinite; var start = DateTime.UtcNow; using (var cur = new QueueCursor(queue)) { var msg = await cur.PeekAsync(Properties.CorrelationId | Properties.LookupId, timeout); for (;;) { if (msg == null) { return(null); } if (msg.CorrelationId == correlationId) { return(queue.Lookup(properties, msg.LookupId, LookupAction.ReceiveCurrent, TimeSpan.Zero, transaction)); } var elapsed = DateTime.UtcNow - start; var remaining = timeout - elapsed; if (remaining <= TimeSpan.Zero) { return(null); } msg = await cur.PeekNextAsync(Properties.CorrelationId | Properties.LookupId, remaining); } } }
/// <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); } }
/// <summary>Creates a new cursor for queue represented by the <paramref name="reader"/>.</summary> public QueueCursor(QueueReader reader) { Contract.Requires(reader != null); _reader = reader; int res = Native.CreateCursor(reader._handle, out _cursorHandle); if (Native.IsError(res)) { throw new QueueException(res); } }
/// <summary>Returns the transactional property of the queue</summary> public static void Purge(string formatName) { using (var q = new QueueReader(formatName)) q.Purge(); }