My backgroundWorker uses ReportProgress to update the ProgressPercentage of a long process.  What happens is in two out of three entries into ProgressChanged ProgressPercentage is zero, whereas every third entry into ProgressChanged the ProgressPercentage is what I would expect.  This happens like clockwork; it is very repeatable.  Here is some simplified code demonstrating my setup (to reduce the length, I've removed the error-handling code):
AutoResetEvent areProgressChanged = new AutoResetEvent(false);
  private void backgroundWorkerProgram_DoWork(object sender, DoWorkEventArgs e)
  {
     bool bRetVal = true;
     int iRetries = 3;
     int iProgress = 0;
     // Repeat Program message and entire sequence until programming
     // is complete or Retries reaches 0...
     do
     {
        bRetVal = Program();
        this.eBgwProgramStatus = BgwProgramStatus.BUSY;
        bRetVal = this.WaitForReceive(SHORT_ACK_WAIT, backgroundWorkerProgram);
        switch (this.eCommsRsp)
        {
           case CommsRsp.ACK:
              this.eBgwProgramStatus = BgwProgramStatus.BUSY;
              iRetries = 3;
              break;
        }
     }
     while ((!backgroundWorkerProgram.CancellationPending)
        && (!bRetVal) && (iRetries > 0));
     // Repeat Write and Data message until programming is complete...
     do
     {
        this.eBgwProgramStatus = BgwProgramStatus.BUSY;
        bRetVal = Write();
        this.eBgwProgramStatus = BgwProgramStatus.BUSY;
        bRetVal = this.WaitForReceive(SHORT_ACK_WAIT, backgroundWorkerProgram);
        switch (this.eCommsRsp)
        {
           case CommsRsp.ACK:
              this.eBgwProgramStatus = BgwProgramStatus.BUSY;
              bRetVal = SendData(pData_c);
              break;
           default:
           case CommsRsp.NACK:
           case CommsRsp.NONE:
              this.eBgwProgramStatus = BgwProgramStatus.NO_ACK_RXD;
              iRetries--;
              bRetVal = false;
              break;
        }
        this.eBgwProgramStatus = BgwProgramStatus.BUSY;
        bRetVal = this.WaitForReceive(SHORT_ACK_WAIT, backgroundWorkerProgram);
        switch (this.eCommsRsp)
        {
           case CommsRsp.ACK:
              this.eBgwProgramStatus = BgwProgramStatus.BUSY;
              iProgress = (this.iProgramSize * 100) / PIC32.ProgMem.Length;
              this.backgroundWorkerProgram.ReportProgress(iProgress);
              this.areProgressChanged.WaitOne();
              iRetries = 3;
              this.iRow++;
              break;
           default:
           case CommsRsp.NACK:
           case CommsRsp.NONE:
              this.eBgwProgramStatus = BgwProgramStatus.NO_ACK_RXD;
              iRetries--;
              bRetVal = false;
              break;
        }
     }
     while ((!backgroundWorkerProgram.CancellationPending)
        && (iRetries > 0)
        && ((!bRetVal) || (this.eBgwProgramStatus == BgwProgramStatus.BUSY)));
  }
  private void backgroundWorkerProgram_ProgressChanged(object sender, ProgressChangedEventArgs e)
  {
     string sProgressPercentage = e.ProgressPercentage.ToString() + "%";
     // Report progress.
     this.labelPercentComplete.Visible = true;
     this.labelPercentComplete.Text = sProgressPercentage;
     this.toolStripStatusLabel.Text = this.sProgramming + sProgressPercentage;
     this.textBoxData.AppendText(this.tBusText.ToString());
     this.textBoxStatus.AppendText(this.tStatusText.ToString());
     this.tBusText.Remove(0, this.tBusText.Length);
     this.tStatusText.Remove(0, this.tStatusText.Length);
     this.areProgressChanged.Set();
  }
(My apologies for the length, but it was requested.)  The same behavior is exhibitted with and without the AutoResetEvent.  Does anyone have any thoughts as to why this may be happenning?  Thanks.
ADDITIONAL DETAILS
If I set a breakpoint on this.backgroundWorkerProgram.ReportProgress(iProgress);, I can see that iProgress increments as expected (slowly, over several intervale, e.g. 0,0,0,1,1,1,2,2,2,3,3,3,etc.).  Then, if I move the breakpoin to string sProgressPercentage = e.ProgressPercentage.ToString() + "%";, the value of e.ProgressPercentage does not match the passed value of iProgress.  What I get is like 0,0,0,0,1,0,0,2,0,0,3,0,0,etc.