Introduction

Performance of pipelines in BizTalk can be enhanced by applying best practices listed in the Optimizing Pipeline Performance article on MSDN. In case you are building a custom pipeline with custom pipeline component that this article is one you definelty need to read before you design, build and deploy your custom pipeline. When requirements drive you to build functionality for inbound messages in a custom pipeline you according to article leverage the VirtualStream, ReadOnlySeekableStream, and SeekAbleReadOnlyStream class found in the Microsoft.BizTalk.Streaming.dll assembly. The VirtualStream class for instance has the same functionality as a MemoryStream class in the System.IO namespace, however it uses disk space to store large streams in stead of memory. Therefore, the benefit of using the VirtualStream class over XmlDocument is that you can gain performance when handling messages, since you do not need to load the entire document into memory using an object.

Developers, who need to build a custom pipeline yet lack awareness of the Microsoft.BizTalk.Streaming.dll assembly, will use the XMLDocument since it has been widely documented. Most developers are quite familair with this class. An instance of the XmlDocument class does rather consume a large amount of memory, which can be up to 10 times the size of the actual message size. With a substantial load of (large) messages the custom pipeline component can become a performance bottleneck.

Building the Sample

Build the sample and deploy to the BizTalk runtime. Then import the binding, create the appropiate file folders.

Description

This sample demonstrate how you can leverage VirtualStream class from the Microsoft.BizTalk.Streaming.dll.

C#
Edit|Remove
    public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) 
            { 
                try 
                { 
                    //If enabled 
                    if (Enabled) 
                    { 
                        //Create StreamReader, VirtualStream and StreamWriter instance 
                        StreamReader sReader = new StreamReader(pInMsg.BodyPart.Data); 
                        VirtualStream vStream = new VirtualStream(); 
                        StreamWriter sWriter = new StreamWriter(vStream); 
      
                        //Write message body to a virutal memory stream 
                        sWriter.Write(sReader.ReadToEnd()); 
                        sWriter.Flush(); 
                        sReader.Close(); 
      
                        vStream.Seek(0, SeekOrigin.Begin); 
      
                        //create a string 
                        string body = new StreamReader(vStream).ReadToEnd(); 
      
                        //Add property to Namespace. 
                        //Manipulate the Namespace of the message 
                        body = body.Replace(OldNamespace, NewNamespace); 
                        vStream.Position = 0; 
      
                        //Write the output 
                        StreamWriter writer = new StreamWriter(vStream); 
                        writer.AutoFlush = true; 
                        writer.Write(body); 
                        vStream.Position = 0; 
      
                        //Put the stream back 
                        pInMsg.BodyPart.Data = vStream; 
      
                    } 
      
                    return pInMsg; 
                } 
                catch (Exception ex) 
                { 
                    if (pInMsg != null) 
                    { 
                        pInMsg.SetErrorInfo(ex); 
                    } 
      
                    throw ex; 
                } 
            } 

Source Code Files

More Information

For more information see also the following TechNet Wiki Article: