进程完成后,C#BackGroundWorker与ProgressBar更新

我在按钮点击事件中有以下内容:

private void buttonSubmitAchChecks_Click(object sender, EventArgs e) { if (backgroundWorker1.IsBusy) return; SubmittingAch(true); backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; label_Status.Text = "Submitting checks to ACH ...."; var qry = from ds in checkTrans.IndividualCheck where ds.SubmitToACH && ds.Status == "Entered" && ds.CheckAmount > 0 && ds.SubmitToACH select ds; if (qry.Count() <= 0) { label_Status.Text = "Nothing to submit. Check the Check Amount, ACH, and Status fields."; } else { progressBar1.Maximum = qry.Count(); progressBar1.Minimum = 0; progressBar1.Step = 1; backgroundWorker1.RunWorkerAsync(qry); } } 

我的backgroundWorker1_DoWork:

 private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { if (backgroundWorker1.CancellationPending) { e.Cancel = true; } else { var qry = e.Argument as EnumerableRowCollection; if (qry != null) { Thread.Sleep(4000); //item.Status = ach.SubmitCheck(item); var ach = new SubmitAchChecks(); foreach (var item in qry) { ach.SubmitCheck(item); backgroundWorker1.ReportProgress(1); Console.Write("backgroundWorker1_dowork=" + progressBar1.Value.ToString() + "\r\n"); } } } } 

我的取消按钮:

 private void cancelAsyncButton_Click(object sender, EventArgs e) { if (backgroundWorker1.WorkerSupportsCancellation == true) { label_Status.Text = "Cancelling..."; backgroundWorker1.CancelAsync(); } } 

我的backgroundWorker1_RunWorkerCompleted:

 private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled == true) { label_Status.Text = "Canceled!"; } else if (e.Error != null) { label_Status.Text = "Error: " + e.Error.Message; } else { label_Status.Text = "Done!"; } SubmittingAch(false); } 

我的backgroundWorker1_ProgressChanged:

 private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value += 1; Console.Write("progressbar1.value=" + progressBar1.Value.ToString() + "\r\n"); } 

当我处理2个项目时,我在调试窗口中得到以下输出:

backgroundWorker1_dowork = 0

backgroundWorker1_dowork = 0

progressbar1.value = 1

progressbar1.value = 2

该事件正在触发,但正如您从console.write中看到的那样,它发生在线程完成之后。 我得到了进度条滚动,但只有一次完成了dowork。

我做错了什么? 我希望在每个项目完成后更新。

这是由于线程的工作方式。 使用BeginInvoke在UI线程上调用ProgressChange ,因此在另一个线程上调用。 同时,工作线程继续运行。 由于没有太多工作要做, BackgroundWorkerBeginInvoke实际调用该方法之前完成其工作,因为每次CPU操作都不会发生线程切换。 它们发生在不少之后。 为避免这种情况,请使用this.Invoke()手动调用增加ProgressBar值的方法。