2011-04-19 33 views
2

我有一个按钮单击事件如下:C#BackgroundWorker的使用进度更新过程完成后

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

这与你的实际问题无关,但我注意到你正在LINQ结果'qry'中检查'ds.SubmitToACH'两次。 – 2011-04-19 02:06:50

+0

谢谢,没有注意到。 – ErocM 2011-04-19 14:00:34

回答

3

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

+0

这就是我所需要的!谢谢!对于那些搜索,这里是一个链接到微软的网站,我用他们的例子,它的工作完美的调用:http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx – ErocM 2011-04-19 14:17:55

相关问题