C# 如果我的函数在处理System.MessageQueue(MSMQ)消息时失败,该消息是否会丢失?

C# 如果我的函数在处理System.MessageQueue(MSMQ)消息时失败,该消息是否会丢失?,c#,msmq,message-queue,C#,Msmq,Message Queue,我使用以下代码发送消息: var transaction = new MessageQueueTransaction()) transaction.Begin( ); var message = new Message { Body = myContent, Recoverable = true }; m_oMessageQueue.Send( message , myTransaction ); transaction.Commit( ); 并使用BeginRecieve

我使用以下代码发送消息:

var transaction = new MessageQueueTransaction())
transaction.Begin(  );

var message = new Message
{
   Body = myContent,
   Recoverable = true
};

m_oMessageQueue.Send( message , myTransaction );

transaction.Commit( );
并使用
BeginRecieve
ReceiveCompleted
事件处理程序接收它

如果我的事件处理程序在调用
EndRecieve
之前失败,消息是否应保留在队列中,并可供后续调用接收?我看到的行为是,信息永远消失了。(或者可能有一个超时,在该点之后它将再次可用?)

更新接收消息的代码如下所示

var messageQueue = new MessageQueue( myPath );
messageQueue.ReceiveCompleted += messageQueue_ReceiveCompleted_ThrowException;
messageQueue.BeginReceive();
出于测试目的,我通过exception事件处理程序在messageQueue_ReceiveCompleted_中引发异常


然后,我用一个工作事件处理程序重复上述代码,但我没有被调用。

最简单的解决方法可能是使用BeginPeek或Peek读取消息的内容,而无需将其从队列中删除,并且在处理完消息后,然后将消息从队列中移除。

问题似乎是您正在将
BeginReceive
用于事务队列:

注意:不要使用异步 调用BeginReceive处理事务。 如果要执行事务性 异步操作,调用 BeginPeek,并将事务和 (同步)接收方法 在您创建的事件处理程序中 用于peek操作。你的活动 处理程序可能包含以下功能: 如下面的C#代码所示


对于这样的失败,我认为消息通常进入死信队列或产生否定的确认,这取决于您如何配置
MessageQueue
(这可以解释为什么您没有看到它们)。您可以。

如果队列是事务性但远程的,则您只能在使用MSMQ 4.0的事务中接收消息

干杯
John Breakwell(MSFT)

您的接收队列的EnableConnectionCache设置为什么?我没有将其设置为任何值,它是用来做什么的?谢谢您的帮助。另一个相关的问题是,如果我使用Peek,消息是否有可能被多个消费者拾取?多个消费者可以
Peek
查看消息,但只有一个消费者能够实际
接收特定消息。这可能需要一些额外的注意,因为两个消费者可能同时在那里-您必须确定他们是在寻找特定的消息(即
Peek
found),还是任何旧消息,并且可能要确保在
Receive
调用中添加一个超时,这样失败者就不会永远阻塞。BeginPeek然后稍后使用PeekCompleted中传递的Id接收BYID是更好的方法吗?