1

我有一个从消息队列中读取消息列表的方法。签名是:

IList<TMsg> Read<TMsg>(MessageQueue queue, int timeout, MessageQueueTransaction tx);

基本功能是它将使用给定事务在超时内从队列中读取尽可能多的消息。我遇到的问题是决定如何最好地执行超时。我目前有两个工作版本。这些都是:

  • 使用 BeginPeek 超时。如果成功,则使用事务性 Receive 调用删除消息。BeginPeek 的超时在每次调用后根据读取开始的时间和当前时间重新计算。
  • 使用带有超时值的接收,并在超时到期时捕获异常。

第一种方法的问题是它需要在 DenySharedReceive 模式下读取队列,否则无法保证消息在 Peek 和 Receive 之间仍然存在。第二种方法的问题是需要抛出和处理异常(尽管是内部透明的),这可能不是一个好的设计,因为每次调用总是以异常结束,这违背了仅在异常情况下抛出异常的想法情况。

有没有人对我如何实现这一点有任何其他建议,或者对这两种技术和我的担忧发表评论?

4

2 回答 2

1

您可以使用响应式扩展来创建消息生产者,使用Observable.Buffer来管理超时,然后订阅该生产者

public IEnumerable<Message> GetMessage()
{
    //do the peek and receive a single message
    yield return message;
}

//and then something like
var producer = GetMessage().ToObservable();

// this is where your timeout goes
var bufferedMessages = producer.Buffer(TimeSpan.FromSeconds(3));

var disp = bufferedMessages.Subscribe(messages =>
    {
        Console.WriteLine("You've got {0} new messages", messages.Count());
        foreach (var message in messages)
            Console.WriteLine("> {0}", message); // process messages here
    });

disp.Dispose(); // when you no longer want to subscribe to the messages

有关更多反应性示例,请查看此处

于 2012-09-21T21:54:33.970 回答
0

经过一番调查,斧头的评论是最接近“答案”的,​​至少就 .NET 而言。包装的本机方法为 'TIMEOUT' 提供返回值(而不是错误值),但这被 .NET 视为异常,重新包装本机代码是不值得的。我试过。:p

于 2012-12-28T01:05:03.060 回答