Reputation: 18743
I have a windows service and a winform application that communicate between each other using WCF through TCP.
I sometimes have to exchange huge data and I encountered a CommunicationException
on the client. Now I have trouble finding which property to change and where (on the server side or the client side?).
The problem occurs when the server is returning a value to the client that is a 2-uple
(my own implementation) of two arrays of doubles: Tuple<Double[], Double[]>
(both arrays have always the same length).
I have noticed that there is no error when the arrays have a length of 22 000
, but the CommunicationException
is thrown when arrays have a length of 44 000
.
Here's my App.config
file regarding the netTcpBinding
part:
<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>
Could you point on which property to change and on which side?
P.S: It's not a timeout problem.
I have now the same nettcpbinding
configuration on both server and client:
<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>
And the same serviceBehavior
:
<behaviors>
<serviceBehaviors>
<behavior name="Debug">
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
I then get a NetDispatcherFaultException
on the client, advising me to increase maxArrayLength
or maxItemsInObjectGraph
. But for me, these values are already largely set for what I need to transfer and also set to the max values!
Here's the InnerException
message:
The maximum array length quota (19502) or the maximum items in object graph quota has been exceeded while reading XML data. These quotas may be increased by changing the MaxArrayLength property on XmlDictionaryReaderQuotas or the MaxItemsInObjectGraph setting.
Any clue? Where does this 19 502
figure comes from?
Upvotes: 1
Views: 2857
Reputation: 1426
On both, the server and client you have to configure the attribute of your binding, if you are exchanging large amounts of data between them. For example:
<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>
Work your way from the large values to find the one that suits you.
EDIT:
In Client side, you need to configure a behavior, and set that behavior in the client endpoint. Something like this:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="debug"> <dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</endpointBehaviors>
</behaviors>
And you set the behavior in the client endpoint:
<endpoint name="myEndpoint" behaviorConfiguration="debug">
Your other settings...
</endpoint>
Hope this helps.
Upvotes: 3
Reputation: 4662
Did you try maxItemsInObjectGraph in your service behavior
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
Upvotes: 1
Reputation: 15163
Here's a copy of a wsHttpBinding that I haved used in tests to successfully transfer huge chunks of data. I'm not saying these values are best practices, but they work to pass big chunks of data.
<binding name="WSHttpBinding_LargeData"
maxBufferPoolSize="524288"
maxReceivedMessageSize="99999999">
<readerQuotas
maxDepth="128"
maxStringContentLength="8192"
maxArrayLength="163840000"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"
/>
</binding>
Upvotes: 1
Reputation: 12904
Personally I would increase the MaxReceivedMessageSize
, ensuring that maxBufferSize
is also adjusted. These are the common areas that we have needed to adjust.
Upvotes: 1