Is it possible to lose messages using MSMQ MessageQueue.Peek with a timeout?

I am currently having a problem with message loss. This error is rare, but often enough to annoy. Here is the context of the problem:

  • I turned on the message log on goldmine_service_queue, MSMQ on a Windows 2003 server.
  • I can prove that the message is inserted in goldmine_service_queue as the message appears in the message log. This information gives information about the time when the message disappeared.
  • Logging functions use http://logging.apache.org/log4net/index.html
  • Logs do not display errors.
  • The worker function (shown below) is executed in the Windows service thread. He is responsible for viewing messages (work items) from the queue and processing them.
  • From the logs, I strongly suspect that my problem may be related to MessageQueue.Peek and timeout.

Is it possible that the timeout and receipt of the message will occur simultaneously? Is there a better way for me to deal with a service stop check to avoid this error?

        private void workerFunction()
    {

        logger.Info("Connecting to queue: " + Settings.Default.goldmine_service_queue);
        MessageQueue q = new MessageQueue(Settings.Default.goldmine_service_queue);
        q.Formatter = new ActiveXMessageFormatter();

        while (serviceStarted)
        {

            Message currentMessage = null;

            try
            {
                currentMessage = q.Peek(new TimeSpan(0,0,30));
            }
            catch (System.Messaging.MessageQueueException mqEx)
            {
                if (mqEx.ToString().Contains("Timeout for the requested operation has expired"))
                {
                    logger.Info("Check for service stop request");
                }
                else
                {
                    logger.Error("Exception while peeking into MSMQ: " + mqEx.ToString());
                }
            }
            catch (Exception e)
            {
                logger.Error("Exception while peeking into MSMQ: " + e.ToString());
            }

            if (currentMessage != null)
            {

                logger.Info(currentMessage.Body.ToString());
                try
                {
                    ProcessMessage(currentMessage);
                }
                catch (Exception processMessageException)
                {
                    logger.Error("Error in process message: " + processMessageException.ToString());
                }

                //Remove message from queue.
                logger.Info("Message removed from queue.");
                q.Receive();
                //logPerformance(ref transCount, ref startTime);
            }


        }//end while

        Thread.CurrentThread.Abort();

    }
+5
source share
3 answers

I do not think that any messages should be left out based on a quick overview, but you are working in a very strange way with a lot of opportunities for the conditions of the race.

ProcessMessage ( ProcessMessage , ). , MSMQ, , , .

, , , ( EndReceive). , ( , MessageQueue.ClearConnectionCache();).

, - , .

+5

, , MSMQ .

" , goldmine_service_queue, .

, goldmine_service_queue. , , AND .

" , MessageQueue.Peek -".

A Peek , . "q.Receive();" . . "Q.Receive();" " ". , - . Peeked ReceiveByID, peeked.

+3

, currentMessage = q.Peek(new TimeSpan(0,0,30)); currentMessage = q.Receive(); . MSMQ , peek ( -), , . Receive , .

: - , , .

mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout

where mqe is the message queue exception. You might like this better than string comparisons.

+1
source

All Articles