Threading and the BizTalk Parallel Shape: The Scatter-Gather Demo
As many of us have learned, BizTalk is not always intuitive. While working on a BizTalk solution, some colleagues and I wondered how we could improve performance in our orchestration. There were some elements to our business process which had the same dependency, and thus could execute in parallel. Perfect opportunity to use the parallel shape! But why? Well, intuition says that the parallel shape should result in many branches in the orchestration executing at the same time and this would require multi-threading. However, this is not how the shape works, or was intended to work.
Time to discover what really happens when using the parallel shape. First, I reviewed the documentation.
"You can place any shape in a parallel branch. Each branch of a parallel runs concurrently but independently." (ms-help://MS.BTS.2006/BTS06CoreDocs/html/cc306f57-d6a6-4830-93b1-a9e3a55df3fd.htm)
I, personally, think the wording here is a little misleading, or at the least, easy to misinterpret. The phrase "runs concurrently" could mean each branch is executing simultaneously in a multi-threaded fashion, or it could mean each branch will execute each of its steps as soon as the necessary resources are available. I found other posts regarding the parallel shape which announced that it, indeed, does NOT result in any multi-threading. But both of the interpretations I came up with for the description in the documentation made me believe that there could be performance gains by using the parallel shape. Sounds like an opportunity to create a sample!
So, I set up my own test With the following goals: to see what the performance gain is, if any, when using the parallel shape, to discover the order that the shapes are executed, and what the threading behavior is. I created two orchestrations. The first does not contain a parallel shape. The second includes the parallel shape. In my sample application (BizTalk Server 2006 R2), I need to make three calls to SQL Server to find products. Just for fun, I also built in delays between the sending of the lookup request, and the receiving of the results. In each orchestration, I log the date and time to the System.Diagnostics.Trace after each message is sent and received, as well as the value of System.Threading.Thread.CurrentThread.ManagedThreadId, just to verify that no additional threads are spawned. Each orchestration was set to run under the same BizTalk Server Host Instance. Here is what the orchestrations look like:
"Linear" Orchestration
"Parallel" Orchestration
Results
As suspected, each entry to the trace showed the same thread ID, proving that no multi-threading is occurring due to the use of the parallel shape. The time stamps from the trace also show that the parallel orchestration completed in about half the time, and that each send occurred almost simultaneously. The delays meant that the next branch in the parallel shape could execute while the previous was waiting. In addition, the following table shows that whichever branch is ready will execute—as you can see, Response 3 is received first, since its delay was the shortest.
For your viewing pleasure, here is the full trace output, along with the path through the parallel orchestration from the orchestration debugger.
Full Trace Output
Parallel Orchestration (Debugger)