如何延迟 Azure 服务总线消息?
How to defer a Azure Service Bus message?
目前我正在使用Microsoft.Azure.ServiceBus.IQueueClient
到RegisterMessageHandler
,然后我收到的消息类型是Microsoft.Azure.ServiceBus.Message
。
According to the documentation:
Message deferral APIs The API is BrokeredMessage.Defer or
BrokeredMessage.DeferAsync in the .NET Framework client,
MessageReceiver.DeferAsync in the .NET Standard client, and
IMessageReceiver.defer or IMessageReceiver.deferAsync in the Java
client.
...但是这些库中的 none 与我实际使用的 类 相关。我该如何推迟?我必须使用什么 类 之类的东西才能延迟消息?上面的所有示例都没有提供足够的代码片段来解释它。
根据@Gaurav 的要求更新
从你的回答中,我可以看到我的消息有 属性:
message.ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddHours(1);
但是queueClient
也有这个方法:
queueClient.ScheduleMessageAsync(message, DateTime.UtcNow.AddHours(1));
我将尝试“scheduledMessageAsync
”,因为我看不到如何在不调用 queueClient
的情况下传达我设置的 ScheduledEnqueueTimeUtc
Microsoft.Azure.ServiceBus.Message
has a property called ScheduledEnqueueTimeUtc
。将来当您希望消息出现在队列中时,只需将此 属性 的值设置为 date/time 值即可。消息将一直隐藏到那个时间,并且只会在 date/time.
出现在队列中
更新
所以我 运行 进行了测试并确认 ScheduledEnqueueTimeUtc
和 ScheduleMessageAsync
都有效。我为 Microsoft.Azure.ServiceBus
SDK 使用了版本 4.1.1
。
这是我写的代码:
static void Main(string[] args)
{
var connectionString = "my-connection-string";
var queueName = "test";
QueueClient queueClient = new QueueClient(connectionString, queueName);
Message msg1 = new Message()
{
Body = Encoding.UTF8.GetBytes("This message has ScheduledEnqueueTimeUtc property set. It will appear in queue after 2 minutes. Current date/time is: " + DateTime.Now),
ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddMinutes(2)
};
queueClient.SendAsync(msg1).GetAwaiter().GetResult();
Message msg2 = new Message()
{
Body = Encoding.UTF8.GetBytes("This message is sent via ScheduleMessageAsync method. It will appear in queue after 2 minutes. Current date/time is: " + DateTime.Now)
};
queueClient.ScheduleMessageAsync(msg2, new DateTimeOffset(DateTime.UtcNow.AddMinutes(2))).GetAwaiter().GetResult();
Console.ReadLine();
}
这是我在 Peek-Lock
模式下获取消息时看到的内容:
使用 BrokeredMessage.Defer 或 BrokeredMessage.DeferAsync 等消息延迟 API 将延迟消息。
推迟邮件会将邮件的状态从活动更改为已延迟。稍后可以根据序列号检索消息。
ScheduleMessageAsync() 用于安排消息的传递(在指定时间发送消息)。收到消息后无法使用
我已经编写了我正在寻找的解决方案,这里是基本大纲:
在异步方法中(运行自己的线程)
public async Task InitialiseAndRunMessageReceiver()
开始无限循环读取消息
receiver = new MessageReceiver(serviceBusConnectionString, serviceBusQueueName, ReceiveMode.PeekLock);
while (true) { var message = await receiver.ReceiveAsync(); ... more code... }
一旦您知道您即将开始您的长期任务,请延迟消息,但存储 message.SystemProperties.SequenceNumber
。这会将它保留在队列中,但会阻止它被重新传送。
await receiver.DeferAsync(message.SystemProperties.LockToken);
当您最终完成后,使用 message.SystemProperties.SequenceNumber
再次请求消息,并像没有延迟一样完成消息
var message = receiver.ReceiveDeferredMessageAsync(message.SystemProperties.SequenceNumber);
receiver.CompleteAsync(message.Result.SystemProperties.LockToken);
您的消息将从队列中删除。
我的大部分困惑是由于库的命名方式相似且寿命重叠造成的。
Microsoft.Azure.ServiceBus.Core.MessageReceiver
就是上面的消息接收者
老问题,但适合我的情况是删除消息并使用 ScheduleMessageAsync 发布副本(某处有复制方法)。然后消息会在所需的时间返回。
目前我正在使用Microsoft.Azure.ServiceBus.IQueueClient
到RegisterMessageHandler
,然后我收到的消息类型是Microsoft.Azure.ServiceBus.Message
。
According to the documentation:
Message deferral APIs The API is BrokeredMessage.Defer or BrokeredMessage.DeferAsync in the .NET Framework client, MessageReceiver.DeferAsync in the .NET Standard client, and IMessageReceiver.defer or IMessageReceiver.deferAsync in the Java client.
...但是这些库中的 none 与我实际使用的 类 相关。我该如何推迟?我必须使用什么 类 之类的东西才能延迟消息?上面的所有示例都没有提供足够的代码片段来解释它。
根据@Gaurav 的要求更新
从你的回答中,我可以看到我的消息有 属性:
message.ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddHours(1);
但是queueClient
也有这个方法:
queueClient.ScheduleMessageAsync(message, DateTime.UtcNow.AddHours(1));
我将尝试“scheduledMessageAsync
”,因为我看不到如何在不调用 queueClient
ScheduledEnqueueTimeUtc
Microsoft.Azure.ServiceBus.Message
has a property called ScheduledEnqueueTimeUtc
。将来当您希望消息出现在队列中时,只需将此 属性 的值设置为 date/time 值即可。消息将一直隐藏到那个时间,并且只会在 date/time.
更新
所以我 运行 进行了测试并确认 ScheduledEnqueueTimeUtc
和 ScheduleMessageAsync
都有效。我为 Microsoft.Azure.ServiceBus
SDK 使用了版本 4.1.1
。
这是我写的代码:
static void Main(string[] args)
{
var connectionString = "my-connection-string";
var queueName = "test";
QueueClient queueClient = new QueueClient(connectionString, queueName);
Message msg1 = new Message()
{
Body = Encoding.UTF8.GetBytes("This message has ScheduledEnqueueTimeUtc property set. It will appear in queue after 2 minutes. Current date/time is: " + DateTime.Now),
ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddMinutes(2)
};
queueClient.SendAsync(msg1).GetAwaiter().GetResult();
Message msg2 = new Message()
{
Body = Encoding.UTF8.GetBytes("This message is sent via ScheduleMessageAsync method. It will appear in queue after 2 minutes. Current date/time is: " + DateTime.Now)
};
queueClient.ScheduleMessageAsync(msg2, new DateTimeOffset(DateTime.UtcNow.AddMinutes(2))).GetAwaiter().GetResult();
Console.ReadLine();
}
这是我在 Peek-Lock
模式下获取消息时看到的内容:
使用 BrokeredMessage.Defer 或 BrokeredMessage.DeferAsync 等消息延迟 API 将延迟消息。
推迟邮件会将邮件的状态从活动更改为已延迟。稍后可以根据序列号检索消息。
ScheduleMessageAsync() 用于安排消息的传递(在指定时间发送消息)。收到消息后无法使用
我已经编写了我正在寻找的解决方案,这里是基本大纲:
在异步方法中(运行自己的线程)
public async Task InitialiseAndRunMessageReceiver()
开始无限循环读取消息
receiver = new MessageReceiver(serviceBusConnectionString, serviceBusQueueName, ReceiveMode.PeekLock);
while (true) { var message = await receiver.ReceiveAsync(); ... more code... }
一旦您知道您即将开始您的长期任务,请延迟消息,但存储 message.SystemProperties.SequenceNumber
。这会将它保留在队列中,但会阻止它被重新传送。
await receiver.DeferAsync(message.SystemProperties.LockToken);
当您最终完成后,使用 message.SystemProperties.SequenceNumber
再次请求消息,并像没有延迟一样完成消息
var message = receiver.ReceiveDeferredMessageAsync(message.SystemProperties.SequenceNumber);
receiver.CompleteAsync(message.Result.SystemProperties.LockToken);
您的消息将从队列中删除。
我的大部分困惑是由于库的命名方式相似且寿命重叠造成的。
Microsoft.Azure.ServiceBus.Core.MessageReceiver
就是上面的消息接收者
老问题,但适合我的情况是删除消息并使用 ScheduleMessageAsync 发布副本(某处有复制方法)。然后消息会在所需的时间返回。