2011-04-19 68 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

相關問題