C # BackgroundWorker ReportProgress ведет себя странно - PullRequest
0 голосов
/ 14 июля 2010

My 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 увеличивается, как и ожидалось (медленно, в течение нескольких интервалов, например0,0,0,1,1,1,2,2,2,3,3,3 и др.).Затем, если я переместлю точку останова на string sProgressPercentage = e.ProgressPercentage.ToString() + "%";, значение e.ProgressPercentage не будет соответствовать переданному значению iProgress.То, что я получаю, похоже на 0,0,0,0,1,0,0,2,0,0,3,0,0 и т. Д.

Ответы [ 2 ]

1 голос
/ 14 июля 2010

Каковы первые несколько значений iProgramSize и PIC32.ProgMem.Length?

Например, если PIC32.ProgramMem.Length было 300, а iProgramSize было 1,2,3,4,5,6 и т. Д., То процент завершения должен быть 0,0,1,1,1,2 и т. Д. 1003 *

Кроме того, вы уверены, что ProgressPercentage передан неправильно, может быть, элемент управления меткой не был обновлен / обновлен правильно?

0 голосов
/ 20 июля 2010

Видимо, эта проблема была как-то введена при оптимизации приложения для масштабируемости. Я, наконец, снова довел программу до «стабильной» точки, перепроверил, и проблема ушла так же загадочно, как и появилась.

...