Session 服务总线-按序列号从会话检索消息

Session 服务总线-按序列号从会话检索消息,session,servicebus,azure-pack,Session,Servicebus,Azure Pack,我当前正在尝试从会话中检索特定消息 为此,我想在消息会话中使用.strongreceive(Int64),在该会话中我传递消息的序列号 这是我的密码- long msgSequenceNr = 1337; QueueClient queueClient = QueueClient.CreateFromConnectionString(Constants.ServiceBusConnectionString, Constants.TestQueueEntityName, ReceiveMode.

我当前正在尝试从会话中检索特定消息

为此,我想在消息会话中使用.strongreceive(Int64),在该会话中我传递消息的序列号

这是我的密码-

long msgSequenceNr = 1337;

QueueClient queueClient = QueueClient.CreateFromConnectionString(Constants.ServiceBusConnectionString, Constants.TestQueueEntityName, ReceiveMode.PeekLock);
MessageSession msgSession = queueClient.AcceptMessageSession(Constants.TestSessionId);

var peekedMsg = msgSession.Peek(msgSequenceNr); // <-- Works fine!
var receivedMsg = msgSession.Receive(msgSequenceNr); // <-- MessageNotFoundException
long msgSequenceNr=1337;
QueueClient QueueClient=QueueClient.CreateFromConnectionString(Constants.ServiceBusConnectionString,Constants.TestQueueEntityName,ReceiveMode.PeekLock);
MessageSession msgSession=queueClient.AcceptMessageSession(常量.TestSessionId);

var peekedsg=msgSession.Peek(msgSequenceNr);// SequenceNumber的Receive只能与Defer方法结合使用。以下是您将如何实施它:

  • 消息已收到,但现在无法处理(可能正在等待另一个进程完成)
  • 将SequenceNumber持久化到一些持久性存储中(表存储、SQL数据库等)
  • 当您知道处理可以继续时(例如:依赖进程已完成),请从持久存储中加载所有SequenceNumber
  • 使用Receive(int sequenceNumber)或ReceiveBatch(int[]sequenceNumber)来接收和处理延迟消息
  • 示例应用程序:

    更新:

    从您的评论中,我注意到“取消错误”延迟消息可能是一个解决方案。下面是一些取消定义消息的示例代码,它将延迟消息复制到新消息,完成延迟消息并将新消息发送回队列。这将使用TransactionScope以事务方式完成并重新发送消息,以避免丢失消息的风险:

        var messageId = "12434539828282";
    
        // Send.
        var msg = new BrokeredMessage {SessionId = "user1", MessageId = messageId };
        msg.Properties.Add("Language", "Dutch");
        queue.Send(msg);
    
        // Receive.
        var session = queue.AcceptMessageSession();
        msg = session.Receive();
    
        // Store the sequence number.
        var sequenceNumber = msg.SequenceNumber;
    
        // Defer.
        msg.Defer();
    
        // Change to true to test if the transaction worked.
        var shouldThrow = false;
    
        // Later processing of deferred message.
        msg = session.Receive(sequenceNumber);
    
        try
        {
            using (var ts = new TransactionScope())
            {
                // Create a new message.
                var undeferredMessage = new BrokeredMessage {SessionId = msg.SessionId, MessageId = msg.MessageId};
                foreach (var prop in msg.Properties)
                    undeferredMessage.Properties.Add(prop);
    
                // Complete and send within the same transaction.
                msg.Complete();
                if (shouldThrow)
                    throw new InvalidOperationException("Some error");
                queue.Send(undeferredMessage);
    
                // Complete the transaction.
                ts.Complete();
            }
        }
        catch (Exception ex)
        {
            msg.Abandon();
        }
    
        if (shouldThrow)
        {
            msg = session.Receive(sequenceNumber);
            Console.WriteLine(msg.MessageId + " should match: " + messageId);
        }
        else
        {
            try
            {
                msg = session.Receive(sequenceNumber);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Message not found, transaction worked OK.");
            }
        }
    

    注意:这里我只是复制了一份属性。请注意,您可能需要复制正文和任何其他附加信息。

    延迟的问题是您无法“取消”它们,不幸的是,这也是我们的一项要求。为了使用Sequence Number receive,您是否需要将此文档记录在需要延迟的地方?Clemens Vasters的帖子:所以我认为应该有一些关于MSDN的信息。谢谢,然后我必须找到另一种方法从会话中检索特定消息@TomKerkhove“Undefer”代码示例是否可以作为场景的选项?初始示例应用程序必须使用旧版本的ServiceBus API/SDK位,许多方法和对象不存在(CreateReceiver、MessageReceive等)