2009-06-02 93 views
0

我有一個基於MSMQ的系統,有三層互相通信。爲了簡便起見,我把它們稱爲第1層,2和3。他們坐在這樣的:兩次接收相同的MSMQ消息?

Layer 1 <-> Layer 2 <-> Layer 3 

所以圖層1次會談二層,三層的會談只有2層,第2層與其他人進行交談。我有四個隊列此,

Layer1_in 
Layer1_out 
Layer3_out 
Layer3_in 

而且層在此基礎通信:

Layer 1 -> Layer1_out -> Layer 2 
Layer 1 <- Layer1_in <- Layer 2 
Layer 3 -> Layer3_out -> Layer 2 
Layer 3 <- Layer3_in <- Layer 2 

(對不起,如果這是不是需要更詳盡的)

總之,一個消息被從傳遞第1層到第2層發生了一些處理,然後另一個(相關)消息被髮送到第3層,反之亦然。我遇到的問題是,偶爾我有兩個消息從第1層發送到第2層,但不是接收這兩個消息,以便它接收第一條消息兩次。我在Layer1_out上使用BeginReceive來異步接收消息。完成後,我會處理收到的消息,並再次致電BeginReceive以獲取下一條消息。

爲了跟蹤這一點,我在發送端實現了一個消息計數器,並將其寫入文本文件。我使用Extension屬性來存儲此消息號的字符串表示,以便我可以在處理端檢索消息號。當我收到一條消息時,我將這個數字寫入另一個文件。這將產生具有相同內容的兩個文件,而是我看到的東西像

00000000000000000214 
00000000000000000215 
00000000000000000215 <- this is bad! 
00000000000000000217 
00000000000000000218 
00000000000000000219 

在收據日誌,表明消息215被處理兩次,216沒有來過。就我的目的而言,它不會影響我處理同樣信息兩次的任何事情(因此,爲什麼在一段時間內沒有注意到這一點),但完全沒有信息是一個大問題。

有什麼想法?

+1

聽起來像Raymond Chen最近的帖子http://blogs.msdn.com/oldnewthing/archive/2009/05/22/9634511.aspx – Ant 2009-06-02 16:02:13

+0

@Ant:有趣的閱讀,但我不知道它有多少影響這個問題,因爲我自己並沒有做任何明確的線程同步(可能有些東西在MSMQ庫的底層完成,但我沒有任何控制權或知識)。也許我錯過了一些東西,但是...你有一個想法如何適用? – 2009-06-02 16:39:57

回答

2

問題解決了......我會在一天內拋出多線程建議,然後被下一次違規自己咬傷!

罪魁禍首就是這條線:

receiveResult = <queueName>.BeginReceive() 

當我有另外的消息已經在排隊等候時,我ReceiveCompleted事件射擊在不同的線程,並讓我EndReceive(receiveResult)調用的返回值之前,從BeginReceive是實際寫入receiveResult變量。因此,我打電話給EndReceive以獲得相同的值,並再次獲得相同的消息!圍繞同步對象鎖定整個事件處理程序處理了這個問題。