我的服务总线队列以前一次处理过一条消息。 我想更改它以允许邮件排队,这样我就可以每隔X秒批量处理它们。我最初这样做了:
var messagingFactorySettings = new MessagingFactorySettings
{
NetMessagingTransportSettings = {
BatchFlushInterval = TimeSpan.FromMilliseconds(10000) },
TokenProvider = credentials
};
现在我想接收这些消息,但似乎我必须在循环中做到这一点,以获得它们:
while ((messages = myQueueClient.ReceiveBatch(1000).ToList()) != null)
{
foreach (var message in messages)
{ ...
据我了解,BatchFlushInterval允许请求在X时间内建立,这样我就不会逐个接收消息,而是批量接收消息。因此,我不确定为什么我不能像以前那样做一些事情:
myQueueClient.OnMessage((m) =>
{
但是批量版本:
myQueueClient.OnBulkMessage((listOfMessages) =>
{
我是否遗漏了某些内容或是否一直在轮询实现这一目标的唯一方法?我的BatchFlushInterval似乎也被忽略了。我希望它只会每隔10秒检查一次新邮件,但它会立即收到第一批邮件,并且所有新邮件也会立即得到处理。
假设我希望每个X(即:1)秒从队列中拉出Y消息(即:1000)并立即处理它们,我将如何做到这一点? 为什么BatchFlushInterval没有任何影响吗?
答案 0 :(得分:1)
看起来似乎是一个简单的Thread.Sleep(x)
。
我发现暂停的问题直到总有一段时间过去很有趣,所以我开始实施一个秒表子类,使问题以更清晰,更易读的方式解决。
while ((var messages = myQueueClient.ReceiveBatch(1000)) != null)
{
var sw = WaitableStopwatch.StartNew();
// ReceiveBatch() return IEnumerable<>. No need for .ToList().
foreach (var message in messages)
{
...
}
// If processing took less than 10 seconds, sleep
// for the remainder of that time span before getting
// the next batch.
sw.Wait(Timespan.FromSeconds(10));
}
/// <summary>
/// Extends Stopwatch with the ability to wait until a specified
/// elapsed time has been reached.
/// </summary>
public class WaitableStopwatch : Stopwatch
{
/// <summary>
/// Initializes a new WaitableStopwatch instance, sets the elapsed
/// time property to zero, and starts measuring elapsed time.
/// </summary>
/// <returns>A WaitableStopwatch that has just begun measuring elapsed time.</returns>
public static new WaitableStopwatch StartNew()
{
WaitableStopwatch sw = new WaitableStopwatch();
sw.Start();
return sw;
}
/// <summary>
/// Waits until the ElapsedMilliseconds property reaches <paramref name="elapsedMilliseconds"/>.
/// </summary>
/// <param name="elapsedMilliseconds"></param>
public void Wait(int elapsedMilliseconds)
{
Wait(TimeSpan.FromMilliseconds(elapsedMilliseconds));
}
/// <summary>
/// Waits until when the Elapsed property reaches <paramref name="elapsed"/>.
/// </summary>
/// <param name="elapsed"></param>
public void Wait(TimeSpan elapsed)
{
TimeSpan diff;
while ((diff = elapsed - this.Elapsed) > TimeSpan.Zero)
{
Thread.Sleep(diff);
}
}
/// <summary>
/// Waits until when the ElapsedMilliseconds property reaches <paramref name="elapsedMilliseconds"/>.
/// </summary>
/// <param name="elapsedMilliseconds"></param>
public Task WaitAsync(int elapsedMilliseconds)
{
return WaitAsync(TimeSpan.FromMilliseconds(elapsedMilliseconds));
}
/// <summary>
/// Waits until when the Elapsed property reaches <paramref name="elapsed"/>.
/// </summary>
/// <param name="elapsed"></param>
public async Task WaitAsync(TimeSpan elapsed)
{
TimeSpan diff;
while ((diff = elapsed - this.Elapsed) > TimeSpan.Zero)
{
await Task.Delay(diff);
}
}
}