多线程MSMQ侦听

时间:2013-01-10 11:12:05

标签: c# msmq

我目前正在阅读我的MSMQ(为简洁而简化):

public void Start()
{
    this.queue.ReceiveCompleted += this.ReceiveCompleted;
    this.queue.BeginReceive();
}

void ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
    this.queue.EndReceive(e.AsyncResult);

    try
    {
        var m = e.Message;
        m.Formatter = this.formatter;

        this.Handle(m.Body);
    }
    finally
    {
        this.queue.BeginReceive();
    }
}

然而,这只允许我以串行方式处理消息。如何修改此代码以允许并行消息处理?

我知道我可以将this.queue.BeginReceive();移出finally并移到ReceiveCompleted的顶部,但是为了阻止产生尽可能多的线程而不是我有消息?我如何明智地控制并行度,以便我不会泛滥线程池?是否有一些内置机制,或者我是否必须自己编写经理?

编辑:我的目标是更快地处理邮件。消息的处理涉及到第三方的异步调用,所以目前我的实现正在浪费大量时间来通过队列。

由于

2 个答案:

答案 0 :(得分:4)

我认为只托管队列阅读器的更多实例会更简单。然后,您可以根据需要通过部署/取消部署更多实例来快速扩展和缩小。

它也成为一种管理,而不是一种发展问题,这就是缩放应该是什么。

答案 1 :(得分:0)

您可以使用“生产者消费者模式”......

.NET 4及更高版本具有Concurrent个集合,这些集合是线程安全的并且实现为“大部分无锁”(因此在多线程中表现良好)......

你可以使用BlockingCollection结合TPL来实现你想要的而不用担心线程池饥饿或类似问题......你只需要将this.Handle(m.Body);行更改为MyBlockingCollection.Add(m.Body);MyBlockingCollection启动“消费者线程”,它可以在this.Handle上运行并执行实际工作(例如,通过调用MyBlockingCollection来调用来自TryTake的下一个项目的{{1}} ...请参阅以上链接获取基本样本...