3

我正在使用 PeekCompleted 从 MessageQueue 读取消息,我在这里执行我的过程,如果一切顺利,我需要将其从队列中删除!目前我正在使用 MyMessageQueue.Receive() 并且它可以工作,但这是确保每条消息都得到正确处理的可靠方法吗?

    MessageQueue MyMessageQueue;
    public Form1()
    {
        InitializeComponent();

        MyMessageQueue = new MessageQueue(@".\private$\Dms");
        MyMessageQueue.PeekCompleted += new PeekCompletedEventHandler(MessageQueue_PeekCompleted);
        MyMessageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
        MyMessageQueue.BeginPeek();
    }

    void MessageQueue_PeekCompleted(object sender, PeekCompletedEventArgs e)
    {
        try
        {
            Debug.WriteLine("ToProcess:" + e.Message.Body);
            //Long process that maybe fail
            MyMessageQueue.Receive();
        }
        finally
        {
            MyMessageQueue.BeginPeek();
        }
    }
4

3 回答 3

4

Receive() 接收队列中的第一条消息,将其从队列中删除。你需要的是MessageQueue.ReceiveById 方法

MyMessageQueue.ReceiveById(e.Message.Id);

其次,我认为,你总是需要调用MessageQueue.EndPeek 方法

Message m = MyMessageQueue.EndPeek(e.AsyncResult);
于 2012-06-29T01:22:09.863 回答
1

如果您总是只有一个队列的接收者,这将起作用 - 另一个进程可以在 BeginPeek 和 Receive 方法之间窥视并接收该消息。上面的 ReceiveById 建议也是如此。

如果您只想要一个接收者,您可以使用 DenySharedReceive 标志打开队列来强制执行此操作。

于 2012-09-25T15:36:08.513 回答
0

我总是尝试使用相同的 BeginPeek() 方法,因为这样,即使消息到达延迟并且完成后 peek 返回时,我也可以让其他作业可以处理,您可以选择消息。我认为上面您只是将代码片段作为示例显示,因为您可能需要编写自己的类/方法来完成新消息检查,以及客户端应用程序中的完整 try 和 catch 块。

于 2012-06-29T01:27:22.020 回答