C# 如何从消息队列中删除消息(仅当其格式正确时)?

C# 如何从消息队列中删除消息(仅当其格式正确时)?,c#,.net-3.5,msmq,C#,.net 3.5,Msmq,我想从一个队列中获取消息并将其发送到数据库。我只想做它,如果它是在特定的格式 如果我直接使用Receive方法,并且在访问消息的Body时发生异常,我将丢失消息,因为MessageQueue的Receive方法将消息从队列中移除 为了避免消息丢失,现在我首先Peek查看消息,如果消息格式正确,我将使用Receive方法将其从队列中删除并发送到数据库 我写的代码是这样的: Message msg = _queue.Peek(new TimeSpan(0, 0, LoggingService.Co

我想从一个队列中获取消息并将其发送到数据库。我只想做它,如果它是在特定的格式

如果我直接使用
Receive
方法,并且在访问消息的
Body
时发生异常,我将丢失消息,因为
MessageQueue
Receive
方法将消息从队列中移除

为了避免消息丢失,现在我首先
Peek
查看消息,如果消息格式正确,我将使用
Receive
方法将其从队列中删除并发送到数据库

我写的代码是这样的:

 Message msg = _queue.Peek(new TimeSpan(0, 0, LoggingService.Configuration.ReceiveTimeout));

// LogMessage is my own class which is adding some more stuff to original message from MessageQueue                
LogMessage message = null;

                if (msg != null)
                {
                    if (!(msg.Formatter is BinaryMessageFormatter))
                        msg.Formatter = new BinaryMessageFormatter();

                    message = LogMessage.GetLogMessageFromFormattedString((string) msg.Body);

                    // Use Receive method to remove the message from queue. This line will we executed only if the above line does not
                    // throw any exception i.e. if msg.Body does not have any problem
                    Message wellFormattedMsg =
                         _queue.ReceiveById(msg.Id);

                      SendMessageToDatabase(message);
                }

首先使用Peek然后再使用Receive的逻辑正确吗?或者还有其他更好的方法来实现同样的目标吗?请注意,我不想一次收到所有的信息。MessageQueue是非事务性的

这与我每次手动将一条消息从队列中取出时所采用的方法相同,我没有遇到任何问题

您似乎没有处理的一件事是如何处理队列中没有所需格式的消息。你打算把它留在队列里吗?如果是这样的话,您可能会得到一个非常大的队列,并且在进一步查看队列中尚未预料到的消息时会遇到各种各样的问题。如果无法删除那些没有所需格式的邮件,则将其从队列中解列并存储在其他位置似乎更有意义。

如果我直接使用Receive方法,并且在访问消息正文时发生异常,我将丢失消息,因为MessageQueue的Receive方法将消息从队列中删除

您应该使用事务性接收,以便在事务中止时消息返回队列

干杯

John Breakwell

我现在投票支持你。你是对的。在我的逻辑中,我进一步将这些格式不好的消息移动到其他队列,这些队列只是为了保留这些有问题的消息而创建的。在我的方法中,我担心如果消息数量太多,并且我们在接收之前查看,是否会导致相当大的性能问题每次都在排队。如果您总是要处理消息或将其移动到另一个队列,则可能不需要peek,因为它不考虑消息的内容,因此您将始终将其退出队列。您是对的。peek根本没有必要。我可以通过处理异常来实现同样的目的。如果我添加此行
message=LogMessage.GetLogMessageFromFormattedString((string)msg.Body)
在try块和exception块中,如果我将消息按原样发送到另一个队列,我会实现我想要的。感谢您的输入。我将其标记为一个答案。无法使用事务,因为消息队列是非事务性的,如问题中所述。很抱歉-最后错过了该位。建议仍然有效。是否有理由使用not首先使用事务性队列?您说希望避免消息丢失,但使用的是非事务性队列。相关