Blog

How to Set up WCF Services to work with large amount of data.

When you are working with WCF Services, sooner or later you will need to either send or receive a large message, like a picture or a pdf document or maybe an object with a complex structure.

If you add a new service to your solution in Visual Studio, by default it is created with a limited message size of 64KB or less. Few pictures or documents will pass through such a small buffer and, if what you are doing is a photo sharing site, it will have little use, if any at all. Fortunately it is very easy to make our services handle large messages properly.
First on the Server’s web.config you must make sure to include the node dataContractSerializer inside the service behavior. You should add the attribute maxItemsInObjectGraph and set the number of items that the service is capable of serializing and deserializing on each request. This will make no difference if your application is sending a few big objects. But in case your service is sending a complex object structure, you may need to tweak this setting.

 
<behavior name="MyServiceLibrary.MyService">
   <serviceMetadata httpsGetEnabled="true" />
   <serviceDebug includeExceptionDetailInFaults="true" />
   <dataContractSerializer maxItemsInObjectGraph="1048576" />
</behavior>
 
In this example the service will serialize an object only if it has less than 1048576 items.
 
Now on the client side you must do some tweaks to the binding node in config file. You should pay special attention to attributes maxBufferPoolSize and maxReceivedMessageSize. Also on the readerQuotas node you should consider the maxStringContentLenght attribute.
 
<binding name="WSHttpBinding_IMyService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:02:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="10485760" maxReceivedMessageSize="8388608" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>

Here the client is able to receive a message from the server up to 8388608 bytes, 8MB
maxBufferPoolSize defines the size of buffer pool, which basically is the amount of memory reserved to store buffers. This means that once a request is finished, it releases the buffer back to the buffer pool, and the next request can use that released buffer instead of creating a new one, which is a costly operation. This, however, impacts in the amount of memory used, so you must consider this factor when making the compromise between availability and performance.
maxReceivedMessageSize is basically the largest message, in bytes, that the client is able to accept. You should set this value according to the size of the message you are expecting to receive.
maxStringContentLength should also be modified to the largest message size we are expecting to receive. A number too low and the message would not be read completely and therefore could not be deserialized in the client. As a rule of thumb, this should be the same as in maxReceivedMessageSize.
And that’s it, once you change these settings your service is ready to accept and send large messages. However, this may not always be the right solution; if your message does not include an image or file and its size is still too large, you may first want to check your class design. Ask yourself if the object could be managed in smaller and more efficient messages, using several requests instead, most of the time it can.
 
Tags: Visual Studio, WCF, maxBufferPoolSize, maxReceivedMessageSize
 

Comments

Leave a comment

 
 
 
 
CAPTCHA Image Validation