C#BackgroundWorker ReportProgress表现奇怪

时间:2010-07-14 16:15:24

标签: c# backgroundworker

我的backgroundWorker使用ReportProgress来更新漫长流程的ProgressPercentage。发生的情况是,ProgressChanged ProgressPercentage中的三个条目中有两个是零,而ProgressChanged ProgressPercentage中的每三个条目都是我所期望的。这就像发条一样;它非常可重复。这是一些简化的代码演示我的设置(为了减少长度,我删除了错误处理代码):

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();
  }

(我对这个长度表示道歉,但是被要求了。)同样的行为表现在有AutoResetEvent和没有this.backgroundWorkerProgram.ReportProgress(iProgress);。有没有人想过为什么会这样?感谢。

其他详细信息

如果我在iProgress上设置断点,我可以看到string sProgressPercentage = e.ProgressPercentage.ToString() + "%";按预期递增(缓慢地,在几个间隔,例如0,0,0,1,1,1,2,2 ,2,3,3,3-等)。然后,如果我将breakpoin移至e.ProgressPercentage,则iProgress的值与{{1}}的传递值不匹配。我得到的是0,0,0,0,1,0,0,2,0,0,3,0,0等。

2 个答案:

答案 0 :(得分:1)

iProgramSize和PIC32.ProgMem.Length的前几个值是什么?

例如,如果PIC32.ProgramMem.Length为300,而iProgramSize为1,2,3,4,5,6等,则完成的百分比应为0,0,1,1,1,2等。< / p>

另外,你确定ProgressPercentage传递不正确,可能是标签控件没有正确更新/刷新吗?

答案 1 :(得分:0)

显然,在优化可伸缩性应用程序时,以某种方式引入了此问题。我终于让程序再次进入“稳定”点,重新测试,问题就像它出现时一样神秘。