【问题标题】:WCF NetTcp service and streaming transfermodeWCF NetTcp 服务和流传输模式
【发布时间】:2014-07-08 13:12:24
【问题描述】:

我在将大型 xml 从客户端发送到 WCF net.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

我没有这样做,我保留了原来的方法签名,但我的客户端仍然可以像以前一样调用服务方法,并且一切都按预期工作。

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

【问题讨论】:

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


    【解决方案1】:

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

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

    这意味着,对于您的 upstream 方法,您将指定一个 Stream 作为参数,它表示您正在向上游发送的数据,对于您的 downstream 方法你指定Stream 作为返回类型,它将包含要读取的数据。

    这在以下ServiceContract中得到了证明:

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

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

    更改这些方法以符合 MSDN 文章中列出的标准,并且您应该正确地流式传输数据。只需确保将整个上行/下行流考虑在内,因为客户端和服务器的情况会相反。

    附带说明,您的异常消息:

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

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

    【讨论】:

    • @DanielKelley 它怎么不回答这个问题?涵盖了Does this mean the streaming transformode is not being used as expected or do I not need to change the method signatures to support streaming?,以及一些关于未分配缓冲区的漫谈。
    • @DanielKelley 谢谢,我将编辑答案以简单地说“是的,你应该”。因为这似乎是你所追求的。如果您觉得它不能回答问题,请随意投反对票。
    • @DanielKelley 谢谢,我已经详细说明了我的答案。
    • @aevitas - 所以在回答我的问题时,我已将绑定传输模式更改为流式传输,但没有更改方法签名,那么为什么方法调用仍然有效,我该如何检查?
    • @aevitas 我看到你已经编辑了你的答案,现在这很有意义:)
    猜你喜欢
    • 1970-01-01
    • 2011-01-02
    • 2013-08-13
    • 2021-06-16
    • 2013-11-24
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多