2013-01-10 19 views
3

我正在從我讀MSMQ像這樣(簡化爲簡潔起見):多線程MSMQ聽

​​

然而,這只是讓我來處理串行消息。如何修改此代碼以允許並行消息處理?

我知道我可以將this.queue.BeginReceive();finally中移出並置入ReceiveCompleted的頂部,但是如何阻止產生儘可能多的線程,並且我有消息?我如何明智地控制並行性的水平,所以我不淹沒線程池?是否有一些內置的機制,或者我必須寫自己的經理?

編輯:我的目標是更快地處理消息。消息的處理涉及到第三方的異步調用,所以目前我的實現浪費了大量的時間來通過隊列。

感謝

回答

4

我認爲這將是簡單的只是主機您的隊列讀者的多個實例。然後,通過部署/取消部署更多實例,您可以根據需要快速擴展和縮減。

此外,它成爲一個管理層,而不是一個發展問題,這就是縮放應該是什麼。

+0

我希望這是這種情況,這將保證消息只處理一次?或者有兩個聽衆有可能收到相同的信息? –

+0

我應該添加的是,您只能通過使用事務隊列來保證。我無法在文檔中找到它,但是我之前已經設置了此擴展機制,並且WCF與msmq的集成提供了一次只能調用一次的屬性,這意味着這是msmq的一項功能。 –

+0

我的隊列是事務性的,有什麼特別的我需要做,或者應該只是工作(tm)? –

0

你可以使用一個「生產者消費者模式」 ......

.NET 4及以上具有Concurrent集合這是線程安全的,實行「多是無鎖」(因此表現良好與多線程)...

你可以使用BlockingCollection與第三方物流相結合,實現你想要什麼,而不線程池飢餓或類似的擔心......你只會更改行this.Handle(m.Body);喜歡的東西MyBlockingCollection.Add(m.Body);和旋轉起來「消費者線程「在0上工作並做實際工作(即調用this.HandleMyBlockingCollection可通過調用TryTake例如獲得下一個項目)......看到上面的鏈接,一個基本的樣本...

+0

這聽起來像我只是在我的隊列末尾做一個非持久的內存中隊列:/ –

+0

如果我有上述代碼的多個實例監聽同一個隊列,MSMQ是否會原子彈出,所以消息只能由一個聽衆處理? –

+0

@AndrewBullock基本上這是一個非持久線程安全的內存中隊列,它可以被多個線程並行使用... – Yahia