我有一个问题,从客户端发送一个大的xml到WCF网。tcp服务和某些机器上的客户端抛出内存不足异常时,方法被调用,我无法在我的本地机器上重现:异常消息:分配33554432字节的托管内存缓冲区失败。可用内存量可能不足。
因此,在阅读解决这个问题的方法时,它似乎是要走的路。因此,我相应地更改了客户端和服务端的绑定:
<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
我没有这样做,我保留了最初的方法签名,但是我的客户端仍然可以像以前一样调用服务方法,并且一切都像预期的那样工作。
这是否意味着流转换模式没有按预期使用,或者我不需要更改方法签名来支持流?你知道我该怎么检查吗?
如果不更改方法签名,则不是严格地流式传输数据,而是完全像以前一样发送数据,而不管服务器配置如何。正如你链接的MSDN文档所述:
- 保存要流的数据的参数必须是方法中唯一的参数。例如,如果输入消息是要流式传输的消息,则操作必须只有一个输入参数。类似地,如果输出消息要流式传输,则该操作必须只有一个输出参数或返回值。
- 参数和返回值中的至少一种类型必须是Stream、Message或IXmlSerializable。
这意味着,对于上游方法,您将指定Stream
作为参数,它代表您向流发送的数据,对于下游方法,您将指定Stream
作为返回类型,它将包含要读取的数据。
这在以下ServiceContract
中得到了证明:
[OperationContract]
Stream GetStream(string data);
[OperationContract]
bool UploadStream(Stream stream);
[OperationContract]
如果你没有像上面演示的那样指定你的方法,你将不会在客户端和服务之间流化你的数据——你将使用与你改变服务器配置之前完全相同的方法。这也是为什么你的方法仍然有效的原因,即使你指定你想在配置中使用流,但没有改变你的方法。
更改这些方法以符合MSDN文章中列出的标准,您应该可以正确地流式传输数据。只要确保你考虑到整个上/下流的事情,因为它将在客户端和服务器端颠倒。
顺便说一下,你的异常消息:
异常消息:Failed to allocate a managed memory buffer of 33554432 bytes。可用内存量可能不足。
表示系统不能为包含数据的底层缓冲区分配32MB的数据。即使正确地实现了流,这个问题也可能继续存在。在正常情况下,32MB的缓冲区应该不是问题。