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.