访问消息正文时出现 EOleException
Windows 服务在尝试访问 MSMQ 消息对象的 .Body 属性时会引发 EOleException - 但仅当此消息中包含的 Xml 文档具有空列表节点时。
EOleException 消息抱怨内存不足(异常代码 -2147024882)。由于异常仅发生在尽可能小的 Xml 文档中,因此内存不可能是真正的问题。接下来想到的是访问权限问题,但所有“好”消息(如下所述)都可以顺利处理。
异常可以在任何可以想到的条件下重现(首先是“坏”消息,首先是许多“好”消息 - 然后是“坏”消息,在调试器中运行或仅记录异常);下面显示的代码是作为服务还是作为简单的可执行文件运行并不重要。
在同一台计算机上的 VBScript 中使用相同的 COM 对象 (MSMQ.MSMQQueueInfo) 不会产生任何错误。
访问除 .Body 之外的任何其他属性都不会引发异常,因此消息对象实例似乎已成功接收。如果未访问 .Body 属性,接收消息的事务也可以成功提交。
Windows 服务代码
//...
qInfo := CreateOleObject('MSMQ.MSMQQueueInfo');
qTxDisp := CreateOleObject('MSMQ.MSMQTransactionDispenser');
//...
qTx := qTxDisp.BeginTransaction;
qMessage := qQueue.Receive(qTx, False, True, 0);
//...
sBody := qMessage.Body; //throws EOleException
对于“坏”消息,qMessage.BodyLength
属性返回值 165,如下所示。
“错误”消息
<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
<query>
<entrylist count="0">
</entrylist>
</query>
</response>
此消息可靠地使服务代码抛出 EOleExecption。
“良好”消息
<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
<query>
<entrylist count="2">
<entry>
<abc>123</abc>
<def>456</def>
</entry>
<entry>
<abc>789</abc>
<def>000</def>
</entry>
</entrylist>
</query>
</response>
该消息已得到可靠处理,没有出现任何问题。
该问题首先出现在将服务从 Win2003 计算机移至 Win2008(32 位标准)时。
A Windows service when trying to access the .Body property of a MSMQ message object throws an EOleException - but only when the Xml document contained in this message has an empty list node.
The EOleException message complains about insufficient memory (exception code -2147024882). Since the exception only occurs with the smallest possible Xml document, memory cannot be the real issue. The next thing that comes to mind is a problem with access rights but then again all "good" messages (as described below) are processed without problems.
The exception can be reproduced under any thinkable condition ("bad" message first, many "good" messages first - then "bad" message, run in debugger or just logging the exception); it doesn't matter if the code shown below is run as a service or as a simple excecutable.
Using the same COM object (MSMQ.MSMQQueueInfo) from within a VBScript on the same machine does not produce any errors.
Accessing any other properties apart from .Body doesn't throw an exception so the message object instance seems to be received sucessfully. Also the transaction receiving the message can be comitted sucessfully if the .Body property is not accessed.
Windows Service code
//...
qInfo := CreateOleObject('MSMQ.MSMQQueueInfo');
qTxDisp := CreateOleObject('MSMQ.MSMQTransactionDispenser');
//...
qTx := qTxDisp.BeginTransaction;
qMessage := qQueue.Receive(qTx, False, True, 0);
//...
sBody := qMessage.Body; //throws EOleException
The qMessage.BodyLength
property returns the value 165 for "bad" messages as shown below.
"Bad" message
<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
<query>
<entrylist count="0">
</entrylist>
</query>
</response>
This message reliably makes the service code throw an EOleExecption.
"Good" message
<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
<query>
<entrylist count="2">
<entry>
<abc>123</abc>
<def>456</def>
</entry>
<entry>
<abc>789</abc>
<def>000</def>
</entry>
</entrylist>
</query>
</response>
This message is reliably processed without problems.
The problem first occured when moving the service from a Win2003 machine to a Win2008 (32-bit Standard).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果VBScript工作正常,那么我猜测这是MSMQ和Delphi服务之间交互的问题。
您是否尝试过在独立应用程序中运行 Delphi 代码?
我还没有使用过 MSMQ,但也许您也可以尝试使用从消息队列中进行非事务性读取来查看它是否有影响(将代码减少到尽可能小/简单)。
一个潜在的原因可能是 Win2008 计算机上有不同的(较新的)MSXML 库。
If the VBScript works fine, then I guess that it is something in the interaction between MSMQ and the Delphi service.
Have you tried to run the Delphi code in a standalone application?
I have not yet worked with MSMQ, but maybe you can also try to use a non transactional read from the message queue to see if it makes a difference (reduce the code to be as small/simple as possble).
A potential reason could be a different (newer) MSXML library on the Win2008 machine.