【问题标题】:Why does BrokeredMessage.RenewLock() only renew the lock for a few seconds?为什么 BrokeredMessage.RenewLock() 只更新锁几秒钟?
【发布时间】:2014-01-29 14:08:10
【问题描述】:

我有一个 BrokeredMessageContext 类,它使用 Timer 定期检查和更新 BrokeredMessage 实例上的锁定,以防处理此消息的进程运行时间超过预期。它通过调用 BrokeredMessage 实例上的 RenewLock() 方法来更新锁。

我希望这个调用给我一个新的锁,它的超时时间与原始锁 (MSDN states that "You can renew locks for the same duration as the entity lock timeout, and there is no maximum duration for a lock renewal.") 相同,但是在调试时,锁超时时间似乎增加了 10-15 秒的“任意”时间。我在 BrokeredMessage 实例上设置了一个监视,我可以看到每次调用 RenewLock() 时 LockedUntilUtc 属性都会增加 10-15 秒。

有人知道为什么会这样吗?有什么办法可以延长锁的更新时间吗?

编辑:

下面迈克的回答是正确的。我发现我实际上是在尝试每十秒更新一次锁从一开始即使我的代码现在打算在锁到期前二十秒之前更新一次锁。这一切都归结为时间比较问题以及我机器上的时间错误的事实(它提前了近一分钟)。哦!

【问题讨论】:

    标签: c# azure servicebus brokeredmessage


    【解决方案1】:

    当您调用 RenewLock 时,它会重置消息被队列或订阅上设置的 LockDuration 锁定的时间,该消息是从中提取的。如果执行更新的类有一个每 10-15 秒触发一次的计时器,那么您看到的行为是正确的。

    示例: 我有一个锁定持续时间为 1 分钟(默认值)的队列。
    我在 UTC 凌晨 1:20 提取消息,因此 LockedUntilUtc 应显示为 UTC 上午 1:21。 如果在处理 10 秒后,我调用 Renew lock,调用将在凌晨 1:20:10 触发,因此 LockedUntilUtc 将变为上午 1:21.10。

    它将锁定持续时间值添加到服务器的当前时间,而不是之前的 LockedUntilUtc 值。这会延长您锁定消息的时间。

    此答案假设您经常触发 Timer 上的触发器,而不是等待接近实际的锁定超时。如果您想更精确,您可以将计时器设置为在锁定到期前大约 10-20 秒触发,然后执行更新锁定。

    【讨论】:

    • 您好迈克,感谢您的回答。这并不反映我所看到的。我的锁定持续时间为 1 分钟,40 秒后我尝试更新锁定。尽管如此,锁定持续时间仅增加了 10 秒左右。
    • 那肯定很奇怪。我快速尝试了这个,LockedUntilUtc 的更新与预期的一样,使用默认的 1 分钟以及其他各种时间。因此,根据您在某个时候的问题,我认为锁会用完,因为您的计时器最终会在“添加”时间后“触发”。你看到了吗?另外,如果您提供一些代码和/或时序示例可能会有所帮助?
    • 我将更新我的问题并将您的答案标记为已接受...在我的代码中添加了大量日志记录后,我发现我可以看到的行为是由于时间比较问题造成的。你的回答完全正确。
    • 小心服务器和客户端机器之间的任何直接时间比较。时钟漂移在任何托管环境中都会发生。
    • 是的。著名的。我已经重写了锁处理程序,所以它只关心锁的持续时间——它不依赖于服务器 UTC 时间和 LockedUntilUtc 的比较。谢谢迈克。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 2021-11-22
    • 1970-01-01
    • 2015-10-28
    • 2019-12-13
    • 2019-08-03
    • 2019-09-15
    相关资源
    最近更新 更多