消息在WCF通信上过大

时间:2011-10-25 16:10:07

标签: c# wcf nettcpbinding

我有一个Windows服务和一个winform应用程序,它们通过TCP使用WCF相互通信。

我有时需要交换大量数据,而我在客户端遇到了CommunicationException。现在我很难找到要更改的属性和位置(在服务器端或客户端?)。

当服务器向客户端返回一个值为2-uple(我自己的实现)的两个双精度数组时,会出现问题:Tuple<Double[], Double[]>(两个数组的长度始终相同)。
我注意到当数组的长度为22 000时没有错误,但是当数组的长度为CommunicationException时,会抛出44 000

以下是关于App.config部分的netTcpBinding文件:

  • 在服务器上:

<netTcpBinding>
    <binding name="MyBindingConf"
             maxReceivedMessageSize="5000000"
             sendTimeout="00:05:00">
        <readerQuotas maxArrayLength="67108864"
                      maxStringContentLength="67108864"/>
        <security mode="None" />
    </binding>
</netTcpBinding>
  • 在客户端:

<netTcpBinding>
    <binding name="MyBindingConf"
             maxReceivedMessageSize="5000000"
             sendTimeout="00:59:00">
        <readerQuotas maxArrayLength="67108864"
                      maxStringContentLength="67108864"/>
        <security mode="None" />
    </binding>
</netTcpBinding>

你能指出要改变哪个属性以及在哪一方?

P.S:这不是暂停问题。


修改

我现在在服务器和客户端上都有相同的nettcpbinding配置:

<bindings>
    <netTcpBinding>
        <binding name="MyBindingConf" 
                 maxReceivedMessageSize="2147483647" 
                 maxBufferSize="2147483647"
                 maxBufferPoolSize="2147483647"
                 sendTimeout="00:30:00">
            <readerQuotas maxDepth="32" 
                          maxStringContentLength="2147483647" 
                          maxArrayLength="2147483647" 
                          maxBytesPerRead="4096" 
                          maxNameTableCharCount="16384" />
            <security mode="None" />
        </binding>
    </netTcpBinding>
</bindings>

同样serviceBehavior

<behaviors>
    <serviceBehaviors>
        <behavior name="Debug">
            <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
    </serviceBehaviors>
</behaviors>

然后我在客户端上获得NetDispatcherFaultException,建议我增加maxArrayLengthmaxItemsInObjectGraph。但对我来说,这些值已基本上设置为我需要传输的值,并设置为最大值!

以下是InnerException消息:

  

读取XML数据时,已超出最大数组长度配额(19502)或对象图配额中的最大项目数。可以通过更改XmlDictionaryReaderQuotas或MaxItemsInObjectGraph设置上的MaxArrayLength属性来增加这些配额。

有任何线索吗?这个19 502数字来自哪里?

4 个答案:

答案 0 :(得分:3)

在服务器和客户端上,如果要在它们之间交换大量数据,则必须配置绑定的属性。例如:

<binding name="LargeSettings" maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000" closeTimeout="01:00:00" openTimeout="01:00:00" receiveTimeout="01:00:00" sendTimeout="01:00:00">
      <readerQuotas maxDepth="32" maxStringContentLength="200000000" maxArrayLength="200000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None" />
    </binding>

从大值开始,找到适合你的方式。

编辑:

在客户端,您需要配置行为,并在客户端端点中设置该行为。像这样:

<system.serviceModel>
    <behaviors>
        <endpointBehaviors>
            <behavior name="debug"> <dataContractSerializer maxItemsInObjectGraph="2147483647" />
            </behavior>
        </endpointBehaviors>
    </behaviors>

并在客户端端点中设置行为:

<endpoint name="myEndpoint" behaviorConfiguration="debug">
    Your other settings...
</endpoint>

希望这有帮助。

答案 1 :(得分:1)

就个人而言,我会增加MaxReceivedMessageSize,确保maxBufferSize也进行了调整。这些是我们需要调整的常见领域。

答案 2 :(得分:1)

这是我在测试中用于成功传输大量数据的wsHttpBinding的副本。我不是说这些值是最佳实践,但它们可以传递大量数据。

    <binding name="WSHttpBinding_LargeData" 
      maxBufferPoolSize="524288" 
      maxReceivedMessageSize="99999999">

      <readerQuotas 
         maxDepth="128" 
         maxStringContentLength="8192" 
         maxArrayLength="163840000" 
         maxBytesPerRead="4096" 
         maxNameTableCharCount="16384"
      />
    </binding>

答案 3 :(得分:1)

您是否在服务行为中尝试了maxItemsInObjectGraph

 <dataContractSerializer maxItemsInObjectGraph="2147483647"/>