Wednesday, July 6, 2011

Transfer large messages in WCF - Part 3

This in continuation with Large Message Transfer in WCF Part 1 and Part 2.

In last article by using Buffered transfer mode and MTOM, we upload a file of 88 mb, we observed memory usage by the application is 400 MB. We will try to transfer same size file by setting transfer mode as Streamed 


<basicHttpBinding>
<binding name="basicHttpStreaming" messageEncoding="Mtom" maxReceivedMessageSize="2147483647" transferMode="Streamed">
</binding>
</basicHttpBinding>
 
Let us upload file of 88 MB size and observe the memory consumption. Below is screen shot of task manager
At any point of time client used max memory of 5 MB where as in buffered mode it was 400 MB


400 MB and 5 MB numbers may vary depend on so many other factors, but my intention here is to show you the memory consumption difference between buffered and streamed transfer mode

Download this code and toggle transfer mode between buffered and streamed and observe memory consumption

Let’s go into some more details on streaming
  1. MTOM helps with transfer overhead and processing performance, but still entire message is still loaded into memory. i.e when we upload a file of size 88MB client will load entire message into memory. Once file is loaded completely service start taking it.
  2. In Streaming as soon as message starts loading into memory, service starts receiving
  3. Streaming will lose fewer features like reliable messaging and message security
  4. Streaming is supported by NetNamedPipeBinding, NetTcpBinding and Basic HttpBinding
  5. Streaming  will expose message body as stream, but header will still buffered
  6. Following are the different options in Transfer Mode
    • Buffered – This is the default setting
    • Streamed- Streams both request and response
    • StreamedRequest – Request is streamed and response is buffered
    • StreamedResponse– Request is buffered and response is streamed
  7. Points to note on when to close stream
    • WCF will close the stream after the final read
      • For Services returning streams
      • For clients sending streams
    • We must close the stream after the final read
      • For clients reading a returned Stream
      • For services reading an incoming stream
Hope this helps
Vital.

3 comments:

  1. I have tried to recive large xml files over to/from WCF. It doesnt work if i set maxStringContentLength="Default value" .it only works when we increases maxStringContentLength but it descreases the performance.Is there any solution to solve this issue without increasing
    maxStringContentLength?

    ReplyDelete
  2. I implemented a WCF service using MTOM and Streamed transfer mode similar to what is described in this article in order to upload large files. I also implemented a C# client that is able to upload very large files to the service without problem. We also need to be able to have a java client upload large files to the same WCF service. I implemented a java client using Axis2 and it seems to work fine for small files but fails with a larger file (4 MB) with an exception and the message "The input stream for an incoming message is null." Does anyone have any thoughts on why a small file sent from Axis2 client works but large file fails?

    ReplyDelete
    Replies
    1. I'm in a similar boat, using Axis2 to create a java client and sending file information thru the WCF to receive a Byte[] on the service side. I too am also getting the "incoming message is null" message. I haven't noticed the issue so much with size as I have noticed it more with file type. I can transfer .txt just fine, but anything else fails (pdf, doc, jpg, etc).

      Delete