我的backgroundWorker
使用ReportProgress
來更新ProgressPercentage
一個漫長的過程。會發生什麼是在三個項目中的兩個入ProgressChanged
ProgressPercentage
爲零,而每ProgressChanged
ProgressPercentage
的第三個條目是我所期望的。這發生像發條一樣;這是非常可重複的。下面是一些簡單的代碼演示我的設置(減少長度,我已經刪除了錯誤處理代碼):C#BackgroundWorker ReportProgress奇怪行爲
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();
}
(對於長度我的道歉,但被要求)。同樣的行爲exhibitted有和沒有AutoResetEvent
。有沒有人有任何想法,爲什麼這可能會發生?謝謝。
額外的細節
如果我設置一個斷點上this.backgroundWorkerProgram.ReportProgress(iProgress);
,我可以看到iProgress
增量預期(慢慢地,在幾個因特瓦勒,如0,0,0,1,1,1,2, 2,2,3,3,3-,等)。然後,如果我將breakpoin移動到string sProgressPercentage = e.ProgressPercentage.ToString() + "%";
,則e.ProgressPercentage
的值與傳遞的值iProgress
不匹配。我得到的就像0,0,0,0,1,0,0,2,0,0,3,0,0等。
而不是僞代碼,爲什麼不給我們一個簡短而完整的例子來說明問題?這會讓你更容易幫助你。 – 2010-07-14 16:19:31
這不是Bgw的正常行爲,所以在你的(真實)代碼中必須有東西引起它。所以我同意Jon的觀點:發佈一個小型演示程序。很可能你會發現一路上的問題。 – 2010-07-14 16:35:34
你有沒有在調試器中通過這段代碼?看起來你只是在非常特定的條件下調用ReportProgress。此外,您傳遞給此方法的值('iProgress')是計算的結果:'(this.iProgramSize * 100)/ PIC32.ProgMem.Length',無論如何。我不清楚,作爲一個外人,你會如何確信這個價值有時不會是零。 – 2010-07-14 16:43:18