我在按钮点击事件中有以下内容:
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<CheckTrans.IndividualCheckRow>;
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完成后才会滚动。
我做错了什么?我希望在每个项目完成后更新。
答案 0 :(得分:3)
这是由于线程的工作方式。使用ProgressChange
在UI线程上调用BeginInvoke
,因此在另一个线程上调用BackgroundWorker
。同时,工作线程继续运行。由于没有太多工作要做,BeginInvoke
在ProgressBar
实际调用该方法之前完成其工作,因为每次CPU操作都不会发生线程切换。它们发生在不少之后。为避免这种情况,请使用this.Invoke()
手动调用增加{{1}}值的方法。