WCF NetTcp服务和流传输模式

时间:2014-07-08 13:12:24

标签: c# .net wcf stream net.tcp

我遇到了从客户端向WCF net.tcp服务发送大型xml的问题,并且当调用我无法在本地计算机上重现的方法时,某些计算机上的客户端会引发内存不足异常: 异常消息:无法分配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

我还没有这样做,我已经保留了原来的方法签名,但是我的客户端仍然可以按照之前的方式调用服务方法,并且它都按预期工作。

这是否意味着流转换器未按预期使用,或者我是否需要更改方法签名以支持流式传输? 我有什么想法可以真正检查吗?

1 个答案:

答案 0 :(得分:2)

如果您不更改方法签名,则不是严格地传输数据,而是完全按照以前的方式发送数据,而不管服务器配置如何。正如您链接的MSDN文档所述:

  • 保存要流式传输的数据的参数必须是方法中的唯一参数。例如,如果输入消息是要流式传输的消息,则操作必须只有一个输入参数。同样,如果要对流输出消息进行流式处理,则操作必须只有一个输出参数或返回值
  • 参数返回值中至少有一种必须是 Stream ,Message或IXmlSerializable。

这意味着,对于上游方法,您应指定Stream作为参数,该参数表示您要向流发送的数据,以及下游方法指定Stream作为返回类型,它将包含要读取的数据。

以下ServiceContract

对此进行了演示
[OperationContract]
Stream GetStream(string data);
[OperationContract]
bool UploadStream(Stream stream);
[OperationContract]

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

更改这些方法以符合MSDN文章中列出的条件,您应该正确地传输数据。只需确保将整个上/下游内容考虑在内,因为客户端和服务器都会反过来。

在旁注中,您的异常消息:

  

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

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