MessageQueue.Send 有时会失败并出现 InvalidOperationException、BadEnumerator
我有一个非 tx 队列,其中一个进程中有一个接收器,还有一个 PowerShell 脚本,该脚本使用 MessageQueue.Send( object, label ) 方法将消息排入队列。 有时我会在 PowerShell 脚本(发送方)中遇到这个奇怪的错误:
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
我无法理解 MessageEnumerator 如何参与发送部分?有什么线索吗?
接收部分(用 .net 编写的服务也使用 System.Messaging 与 MSMQ 交互)正在 while 循环中完成工作,在该循环中它执行一个 queue.Peek( 1s timeout ),然后调用到queue.Receive()。 所有 MSMQ 异常均由接收方记录,但日志为空。所有错误都发生在发送 PowerShell 脚本中。
接收器是已知的旧代码,但脚本是新的且未经测试。 在我的测试过程中,我在没有连接接收器的测试机器上没有出现任何错误。
第一次拍摄连接接收器时,对 MessageQueue.Send() 的一些调用导致了错误。
该脚本看起来像这样:
begin {
$q = Create-QueueInstance
}
process {
$messagesToSend | %{
Send-Message $q $_
}
}
end {
$q.Dispose()
}
第二次尝试在每次迭代中处理队列实例,如果问题与未释放共享资源等有关:
该脚本看起来像这样:
process {
$messagesToSend | %{
$q = Create-QueueInstance
Send-Message $q $_
$q.Dispose()
}
}
错误仍然发生,但我相信它发生了不太频繁。
我使用默认构造函数来创建队列实例,没有自定义 DefaultPropertiesToSend 或任何内容。 这些消息是 XML 可序列化对象,生成大约 300 字节的消息正文。 队列、发送者和接收者位于同一台机器上。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为什么该服务要执行先查看后接收的操作?
它是否检查该消息是否是它想要的消息?
如果是这样,您是否使用 PeekNext 来向下移动队列?
接收者服务是多线程的吗?
只是想弄清楚光标进入的位置。
很奇怪的问题。
干杯
约翰·布瑞克威尔
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