2014-07-08 53 views
2

我有一个从客户端发送一个大的XML到WCF net.tcp服务的问题,并且某些机器上的客户端在调用方法时会引发内存不足异常,而我无法在我的本地机器上重现: 异常消息:无法分配33554432字节的托管内存缓冲区。可用内存量可能很低。WCF NetTcp服务和流式传输模式

因此,通过阅读方式来解决这个问题,它接缝流是一种方式。 所以我改变了客户端都与服务相应的绑定:

<netTcpBinding> 
     <binding name="NetTcpBinding_IPricerDataService" closeTimeout="00:10:00" transferMode="Streamed" 
      openTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647" 
      maxReceivedMessageSize="2147483647" /> 
</netTcpBinding> 

不过,我的印象是,这意味着还改变服务方法签名使用的是流参数下: http://msdn.microsoft.com/en-us/library/ms789010(v=vs.110).aspx

我没有做到这一点,我已经离开了方法签名,因为他们原来是这样,但我的客户仍然可以按照以前的方式调用服务方法,并且所有这些都按预期工作。

这是否意味着流式转换代码没有按预期方式使用,还是我不需要更改方法签名以支持流式传输? 任何想法我怎么能真正检查?

回答

2

如果您不更改您的方法签名,那么您不是严格按照以前的方式发送数据,而是发送它,而不管服务器配置如何。作为MSDN文档您链接状态:

  • 保存数据的参数来进行流必须在方法的唯一参数。例如,如果输入消息是要传输的消息,则该操作必须只有一个输入参数。同样,如果输出消息要流式传输,则该操作必须具有一个输出参数或返回值
  • 至少类型参数返回值中的一个必须是,消息,或IXmlSerializable的。

这意味着,为您上游方法,你指定一个Stream为参数,其表示数据要发送了该流,并为您的下游方法指定Stream作为返回类型,它将包含要读取的数据。

这表现在以下ServiceContract

[OperationContract] 
Stream GetStream(string data); 
[OperationContract] 
bool UploadStream(Stream stream); 
[OperationContract] 

如果如上所示不指定你的方法,你就不会结束,客户端和服务之间的流数据 - 你将使用与您在更改服务器配置之前完全相同的方法。这也是为什么你的方法仍然有效的原因,即使你指定了你想在配置中使用流媒体,但没有改变你的方法。

更改这些方法以符合MSDN文章中规定的标准,并且您应该正确地传输数据。只要确保你考虑了整个上/下游的事情,因为它会颠倒的客户端和服务器。

在一个侧面说明,你的异常消息:

异常消息:无法分配的33554432个字节的管理存储器缓冲器。可用内存量可能很低。

指示系统无法为包含数据的底层缓冲区分配32MB的数据。即使您正确实施流式传输,此问题仍可能继续存在。在正常情况下,32MB缓冲区应该不成问题。

+0

@DanielKelley它不能回答这个问题吗? '这是否意味着流式转换代码没有按预期使用,或者我不需要更改方法签名以支持流式传输?“,以及一些关于未分配缓冲区的说法。 – aevitas

+0

@DanielKelley谢谢,我会编辑答案,简单地陈述“是的,你应该。”因为这似乎是你的追求。如果你觉得它没有回答这个问题,请随时downvote。 – aevitas

+0

@DanielKelley谢谢,我详细阐述了我的答案。 – aevitas