views:

170

answers:

2

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.

+1  A: 

What are the first few values of iProgramSize and PIC32.ProgMem.Length ?

For example if PIC32.ProgramMem.Length was 300, and iProgramSize was 1,2,3,4,5,6 etc, then the percentages complete should be 0,0,1,1,1,2 etc.

Also, are you sure the ProgressPercentage is passed incorrectly, could be it that the label control not be updated/refreshed correctly?

sgmoore
`iProgramSize` starts out as 0 and increments to `PIC32.ProgramMem.Length`, which is a fixed value in this part of the application of about 512K.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.
Jim Fell
Strange. I assume the e.ProgressPercentage ends with values like 98,0,0,99,0,0,100 and presumably a workaround would be not to update the labels if e.ProgressPercentage is zero.Is the number of incorrect values (zeros) related to the number of repeated inputs, ie if you change your iProgress to be = (this.iProgramSize * 50) / PIC32.ProgMem.Length does this mean you end up with more zeros between the correct values?
sgmoore
Apparently, this problem was somehow introduced while optimizing the application for scalability. I finally got the program to a "stable" point again, retested, and the problem has gone away just as mysteriously as it appeared. I've up-voted your response because you gave my query some critical thought, tried to help, and didn't just dismiss it. Kudos!
Jim Fell
A: 

Apparently, this problem was somehow introduced while optimizing the application for scalability. I finally got the program to a "stable" point again, retested, and the problem has gone away just as mysteriously as it appeared.

Jim Fell