在WCF服务中使用GetReaderAtBodyContents的“意外的文件结束”

时间:2009-08-13 08:26:06

标签: xml wcf wcf-binding

我正在运行一个Web服务,它通过自定义绑定接受SOAP消息。

正确分派消息,并且大多数消息都处理得很好。在处理消息时,使用以下命令将消息读取到XmlDocument:

XmlDocument doc = new XmlDocument();
try {
    doc.Load(msg.GetReaderAtBodyContents());
} catch (XmlException x) {
    e = x;
} catch (IOException x) {
    e = x;
}

但是,当服务上的负载增加时(可能是一个线程问题?无法想象,因为在我的自定义传输通道使用WebMessageEncoder创建消息后,其他任何地方都没有访问消息),尽管如此,很少会抛出XmlException。输入消息没问题。

  

意外的文件结束。以下   元素未关闭:A,B,Body,   信封。第28行,第9位。

因为我在这一行的代码中放了一个断点,所以我可以查看msg.ToString()的当前值,它给出了一个XML文件,该文件在http://www.validome.org/xml/validate/等验证器中得到了很好的验证。 p>

请注意,调用msg.ToString()并不总是必须正常工作,因为正文也可以是一种流形式,只能使用msg.GetReaderAtBodyContents()上的阅读器读取一次。

这种奇怪行为的原因似乎是我的自定义绑定,因为它可以通过WebHttpBinding在25000个请求上正常工作。

在我的传输通道中,我在从输入源向byte []体提取消息后使用此代码。

Message message = encoder.ReadMessage(
new ArraySegment<byte>(body, 0, contentLength), bufferManager, contentType);

之后应用标头,然后将消息直接放入RequestContext的RequestMessage属性中。我必须在错误中遗忘一些东西。但是什么?

1 个答案:

答案 0 :(得分:1)

问题是,我调用了编码器.ReadMessage两次,有一条消息用于调试输出,另一条用于传递给RequestContext。不幸的是,ReadMessage将byte []缓冲区返回给池。如果加载增加,另一个线程可以获取两个ReadMessage调用之间的缓冲区并用自己的东西覆盖它。由于第二条消息已转发到ServiceModel,因此可能会因此过程而损坏。