2

I have a non-tx queue with a receiver in one process and a PowerShell script which uses the MessageQueue.Send( object, label ) method to enqueue messages. Occasionally I get this weird error in the PowerShell script (the sender):

An error occurred while enumerating through a collection: Message that the cursor is   currently pointing to has been removed from the queue by another process or by another call to Receive without the use of this cursor..
+ CategoryInfo          : InvalidOperation: (System.Messaging.MessageEnumerator:MessageEnumerator) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration

I can't understand how the MessageEnumerator gets involved in the sending part? Any clues?

The receiving part (service written in .net also using System.Messaging to interact with MSMQ) is doing its work in a while loop in which it does a queue.Peek( 1s timeout ) and then a call to queue.Receive(). All MSMQ exceptions are logged by the receiver, but the log is empty. All errors occurs in the sending PowerShell script.

The receiver is old known-to-be-working code but the script is new and untested. During my tests I got no errors on the test machine, where no receiver was hooked up.

First shot with the receiver hooked up, some of the calls to MessageQueue.Send() resulted in an error.

That script looked like this:

begin {
    $q = Create-QueueInstance
}
process {
    $messagesToSend | %{
        Send-Message $q $_
    }
}
end {
    $q.Dispose()
}

Second shot I tried to dispose the queue instance in each iteration, if the issue was related to shared resources not being freed up, etc:

That script looked like this:

process {
    $messagesToSend | %{
        $q = Create-QueueInstance
        Send-Message $q $_
        $q.Dispose()
    }
}

The error still occurs, but I believe it occurs less frequent.

I use the default constructor to create the queue intance, no customization of DefaultPropertiesToSend or anything. The messages are XML serializable objects, producing about a message body of 300 bytes. The queue, sender and receiver are located on the same machine.

Johan Andersson
  • 185
  • 2
  • 8

1 Answers1

0

Why does the service do a Peek-then-Receive?
Is it checking that the message is the one it wanted or not?
If so, do you use PeekNext to move down the queue?
Is the receiver service multi-threaded?
Just trying to work out where cursors comes into it.

Pretty weird problem.

Cheers John Breakwell

John Breakwell
  • 4,667
  • 20
  • 25
  • 1. I really don't know but I believe it is a guard if the processing of the message fails. 2. It's not checking the message, the process is actually Peek-Process-Receive 3. No, it's using this call: queue.Peek( new TimeSpan( 0, 0, 1 ) ) 4. Well, yeah. It is a Windows Service starting a thread, but that thread is the only one consuming messages from the queue. Thanks for all the good questions! – Johan Andersson Jan 19 '11 at 07:55
  • Yes, the Peek-then-receive is a classic way of handling messages in case of failure in older versions of MSMQ. You should be using transactional receives, though, on MSMQ 4.0 or above. – John Breakwell Jan 28 '11 at 02:56