Buffer size in WCF service

16,500

Solution 1

It sounds like sheer data overload. Pagination, as noted in comments, is a practical solution. If there is a good reason to want the 80k, you could try using a different mechanism to serialize the data. For example, protobuf data is generally much smaller than xml, so you might try using that on the wire. However, since this is Silverlight I can't (currently) swap this automatically - you would need to return a byte[] or Stream and handle the serialization/deserialization explicitly at the server/client. This should drop the bandwidth requirements by a fair whack (even more if you can configure Silverlight to use MTOM - I haven't checked lately, but this wasn't supported in some earlier releases).

Solution 2

As your proc returns 80K, you have to add your buffer size at Client end as well.

readerQuotas

<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>

This should work. If required increase your buffer size.

Solution 3

We have successfully used GZIP compression between the Client and the WCF service to increase the number of rows we could pull back. Should also work for your needs.

We used the MS libraries to achieve it: http://msdn.microsoft.com/en-us/library/ms751458.aspx

Share:
16,500
Kev
Author by

Kev

Updated on June 16, 2022

Comments

  • Kev
    Kev almost 2 years

    We have a WCF service which executes certain stored procedures and returns the results to the silverlight client. Some of the stored procedures return upto 80K rows.

    Given below are the settings in web.config for Service

    <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
        <behaviors>
           <serviceBehaviors>
               <behavior name="MyService.MyServiceBehavior">
                   <serviceMetadata httpGetEnabled="true"/>
                   <serviceDebug includeExceptionDetailInFaults="true"/>
                   <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
               </behavior>
           </serviceBehaviors>
        </behaviors>
        <bindings>
           <basicHttpBinding>
               <binding name="BasicHttpBinding_MyService" 
                    maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" 
                    receiveTimeout="00:40:00" openTimeout="00:40:00" 
                    closeTimeout="00:40:00" sendTimeout="00:40:00">
                    <readerQuotas maxDepth="2147483647" 
                        maxStringContentLength="2147483647" maxArrayLength="2147483647" 
                        maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
                    <security mode="None"/>
               </binding>
            </basicHttpBinding>
            <customBinding>
               <binding name="MyService.MyService.customBinding0">
                  <binaryMessageEncoding/>
                  <httpTransport/>
                </binding>
            </customBinding>
         </bindings>
         <services>
              <service behaviorConfiguration="MyService.MyServiceBehavior" 
                       name="MyService.MyService">
                  <endpoint name="BasicHttpBinding_MyService" 
                      address="" 
                      binding="basicHttpBinding" 
                      bindingConfiguration="BasicHttpBinding_MyService" 
                      contract="MyService.IMyService"/>
               </service>
         </services>
    </system.serviceModel>
    

    And this for Client

    <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 
        <behaviors>
           <serviceBehaviors>
               <behavior name="MyService_Behavior">
                  <serviceDebug includeExceptionDetailInFaults="true"/>
                  <serviceMetadata httpGetEnabled="true"/>
               </behavior>
           </serviceBehaviors>
           <endpointBehaviors>
              <behavior name="r1">
                  <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
              </behavior>
           </endpointBehaviors>
        </behaviors>
        <bindings>
           <basicHttpBinding>
                <binding name="BasicHttpBinding_MyService" 
                    closeTimeout="00:03:00" openTimeout="00:03:00" 
                    receiveTimeout="00:10:00" sendTimeout="00:03:00" 
                    allowCookies="false" bypassProxyOnLocal="false" 
                    hostNameComparisonMode="StrongWildcard" 
                    maxBufferSize="2147483647" maxBufferPoolSize="2147483647" 
                    maxReceivedMessageSize="2147483647" 
                    messageEncoding="Text" textEncoding="utf-8" 
                    transferMode="Buffered" useDefaultWebProxy="true">
                   <security mode="None"/>
                 </binding>
            </basicHttpBinding>
         </bindings>
         <client>
            <endpoint name="BasicHttpBinding_MyService"
                address="http://localhost:8080/MyService/MyService.svc" 
                behaviorConfiguration="r1"
                binding="basicHttpBinding" 
                bindingConfiguration="BasicHttpBinding_MyService" 
                contract="MyService.IMyService"  />
        </client>
    </system.serviceModel>
    

    Whenever the number of records go beyond 20K, the service throws an error as either TimeOut or NotFound. Why do you think this happens n how do I fix it?