A trap for young players
A customer of mine bumped into an interesting trap when building a BizTalk Orchestration. Basically, they have a fairly complex orchestration, and at various points in this orchestration, they needed to write some information to an Oracle databse. They wrote a simple OracleHelper component, and tested and debugged that. Then they added a whole lot of expression shapes in the orchestration, where each expression shape had a line something like this...
bResult = bErrorOccurred || OracleHelper.UpdateApplicationStatus(statusFlag);
The intent was that if Oracle access failed (for example if the Oracle Server was not available), then the result flag would be updated, and we would know whether or not a DB update was successful.
The customer rang me to say that orchestration was sometimes not calling the Oracle helper component, and this behaviour was very inconsistent. He blamed BizTalk.
Now orchestrations are converted to intermediate C# code, and then compiled. If you show this expression to an experienced C# coder, they'll quickly point out to that this is very bad code. The problem is that the C# compiler will attempt to do expression optimisation. If you execute this expression, and bErrorOccurred is true, then bResult will always be true, so the C# compiler will remove the call to the OracleHelper, because the outcome of this call cannot affect the final result of the expression. The C# compiler will change this code to
bResult = bErrorOccurred;
Once I pointed this put, they changed the code to
bResult = OracleHelper.UpdateApplicationStatus(statusFlag) || bErrorOccurred;
and everything worked fine. I guess BizTalk is predictable and consistent after all :-)