Share via


Streaming and ToString

WCF supports message transfers using either a streamed or buffered data model. A buffered model uses contiguous blocks of memory to store the data. A streamed model provides an extra layer of indirection to buffers. The streamed model uses an interface for reading and writing portions of the data to buffers but abstracts the data storage. Working with streamed data is more complicated than working with buffered data but the benefit is that the streamed data model does not have to fit the data into a contiguous block of memory. The streamed data model is free to use multiple blocks, multiple types of stores, or just throw away parts of the data once they're no longer needed.

Most of the data access methods in WCF hide the distinction between buffering and streaming by offering both data models regardless of the native underlying model. However, as a user of the data model, you should care about the underlying model even though the API doesn't seem to make it a big deal. If you treat a large streamed message like it was buffered, then you are basically losing the advantages of having streamed the content.

The ToString method on the other hand is ambiguous about its treatment of streamed messages. Normally, asking to read the complete contents of a streamed message would result in buffering. Although there is no contract for what ToString produces, it would be unexpected to perform a tremendous amount of work, such as this buffering. Therefore, calling ToString on a standard streamed message skips over the contents of the message. This also allows ToString to work without consuming the contents of the message and requiring that you make a copy of the message beforehand.

Some people want to always see the contents of the message in ToString because they're using the ToString output for some purpose, such as message logging. I have seen suggestions that calling CreateBufferedCopy works around this difficulty because ToString gives you the whole message when the message is buffered. These suggestions are incorrect. Despite the name, CreateBufferedCopy isn't guaranteed to give you a buffered message or a message that you can ToString in this way. The contract of CreateBufferedCopy is to create a MessageBuffer from which you can stamp out many copies of the message contents. There are no promises about whether those stamped messages will be buffered or streamed. The correct way to read all of the contents of a streamed message is to read all of the contents. For example, attach an XML reader to your copy of the message and keep calling read until the message is done. There is no shortcut around consuming the message.

Next time: XML Processing Instructions