4

我调用client.Send(brokeredMessage);了一次,但我收到了几次消息。对于句柄队列,我使用此代码

private static void HandleQueue(string queueName, MessageHandler messageHandler)
        {
            // Create the queue if it does not exist already
            string connectionString =
                Configuration.GetConnectionString("Microsoft.ServiceBus.ConnectionString",false);

            var namespaceManager =
                NamespaceManager.CreateFromConnectionString(connectionString);

            if (!namespaceManager.QueueExists(queueName))
            {
                namespaceManager.CreateQueue(queueName);
            }

            QueueClient client =
                QueueClient.CreateFromConnectionString(connectionString, queueName);

            while (true)
            {
                BrokeredMessage message = client.Receive();

                if (message != null)
                {
                    try
                    {    
                        messageHandler(message);

                        // Remove message from queue
                        message.Complete();
                    }
                    catch (Exception)
                    {
                        // Indicate a problem, unlock message in queue
                        message.Abandon();
                    }
                }
            }
        }

问题是BrokeredMessage message = client.Receive();多次调用并返回相同的消息,如果执行messageHandler(message);需要很长时间。我该如何解决?

4

3 回答 3

11

在您处理消息时,消息正在解锁。为消息设置锁定超时的正确位置是QueueDescription http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.lockduration.aspx

此处允许的最长时间为 5 分钟,因此如果您需要更长时间地处理消息,则可以调用RenewLock该消息以继续使其对其他消费者不可见。您是对的,在您完成处理之前调用Complete是不可取的,因为如果您处理崩溃,那么您将不会再次收到消息。

当消息从队列中显示给消费者时,上面提到的属性BrokeredMessage.ScheduledEnqueueTimeUtc用于“延迟”。假设您在第 1 天发送消息并将预定时间设置为第 2 天,那么Recieve直到第 2 天呼叫才会返回消息。

于 2013-07-23T10:20:30.663 回答
1

如果您的消息在允许的时间内没有得到处理,听起来您的消息会返回队列(根据您的描述,它仅在 messageHandler 运行很长时间时才会发生)。

听起来您想增加消息的可见性超时,以便它们不会这么快安静地返回队列。对于 ServiceBus,这意味着如果消息尚未完成,则预先计算消息重新出现的时间

http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.scheduledenqueuetimeutc.aspx

于 2013-07-23T03:37:56.533 回答
1

你应该做几件事:

  1. 在您的 While(true) 循环中引入睡眠时间。可以说,Thread.Sleep(30000);
  2. 检索消息内容并将消息标记为完成。然后将检索到的内容传递给您的消息处理程序,而不是消息本身。等待“messagehanfler”完成不是一个好习惯。
  3. 如果在处理过程中消息处理程序内部发生错误,则将另一条具有相同内容的代理消息排队。
  4. 处理有毒信息。检查每条代理消息的传递计数,如果传递计数超过 n 次,例如 5 次,则删除该消息。

希望能帮助到你!

于 2013-07-22T19:31:25.450 回答