0

我有一个基于 MSMQ 的系统,它具有相互通信的三层。为简单起见,我将它们称为第 1、2 和 3 层。它们的位置如下:

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

因此,第 1 层仅与第 2 层对话,第 3 层仅与第 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 层发送两条消息,但不是按顺序接收两条消息,而是两次接收第一条消息。我正在使用BeginReceiveonLayer1_out异步接收消息。完成后,我处理收到的消息并BeginReceive再次调用以获取下一条消息。

为了追踪这一点,我在发送端实现了一个消息计数器,并将其写入文本文件。我正在使用该Extension属性来存储此消息号的字符串表示形式,以便我可以在处理端检索消息号。当我收到一条消息时,我将这个号码写入另一个文件。这应该产生两个具有相同内容的文件,但我会看到类似的东西

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

在回执日志中,表明消息 215 被处理了两次,而 216 没有通过。就我的目的而言,两次处理同一条消息对我没有任何影响(因此这在一段时间内一直未被注意到),但完全丢失一条消息是一个大问题。

有什么想法吗?

4

1 回答 1

2

问题解决了......我想有一天我会给出多线程建议,然后我自己就会被违规咬到!

罪魁祸首是这一行:

receiveResult = <queueName>.BeginReceive()

当我有另一条消息已经在队列中等待时,我的ReceiveCompleted事件在另一个线程上触发并EndReceive(receiveResult)在返回值BeginReceive实际写入receiveResult变量之前到达我的调用。结果,我EndReceive用相同的值调用并再次收到相同的消息!围绕同步对象锁定整个事件处理程序可以解决这个问题。

于 2009-06-02T17:30:45.680 回答