Owen found a bug today in the custom party resolution SDK pipeline component located in @ $:\Program Files\Microsoft BizTalk Server 2004\SDK\Samples\Pipelines\CustomPartyResolution. 

 

The bug is in the Read() method in the PartyResolutionStream class:

 

public override int Read(byte[] buffer, int offset, int count)
{
      int ReturnValue = mBaseStream.Read(buffer, offset, count);

if(mFirstRead)
      {
            mFirstRead = false;
            if(mFirstReadCallback != null)
                  mFirstReadCallback();
      }
      if(ReturnValue != 0)
            if(mReadCallback != null)
                  mReadCallback();
      else if(mLastReadCallback != null)
            mLastReadCallback();

      return ReturnValue;
  }

For those of you not familiar with the sample, it demonstrates how to implement an eventing stream to help process message data in a streaming fashion, one reason why this is important is because properties are only guarenteed to be promoted once the stream has been read in its entirety. If you need to read a a particular property that the dissassembler is going to promote, your down stream pipeline component will need to wait until the end of stream event has been fired in order to guarentee the dissassembler has promoted it. I'll drill down to this in more detail sometime soon.

The problem with the sample code is that mLastReadCallback delegate gets called even when the end of the stream hasn't been hit. This is because the last else in the code was being matched against the preceeding if. The fix is pretty trivial, {}’s need to be added to the last if, this is a great example of why constructs such as if should always use {} even if they are only on a single line:

 

public override int Read(byte[] buffer, int offset, int count)
{
      int ReturnValue = mBaseStream.Read(buffer, offset, count);

      if(mFirstRead)
      {
            mFirstRead = false;
            if(mFirstReadCallback != null

            {
                  mFirstReadCallback(); 

            }
      }
      if(ReturnValue != 0)
      {
            if(mReadCallback != null

            {
                  mReadCallback(); 

            }
      }
      else if(mLastReadCallback != null)

      { 
            mLastReadCallback();

      }

      return ReturnValue;

}

 

Also, I'm in the process of cleaning up the sample code for part 2 of ACK's/NACK's and will hopefully get that posted in the not too distant future.