通过backgroundworker在方法中更新进度栏

时间:2018-12-03 14:45:36

标签: c# winforms methods progress-bar backgroundworker

我的程序(使用Windows窗体在C#中)正在读取和解析大量数据,而我正在使用Backgroundworker,后者调用这些全局方法(读取和解析)。我想让用户了解需要花费多长时间,因此Backgroundworker应该显示其正在执行的操作,并具有一个进度条,该进度条也应适合每个单独的操作。

不幸的是,我无法使其正常工作,因为进度条根本没有更新,只是保持空白。

这是我到目前为止所拥有的:

run_with_configuration

在方法中看起来像这样:

        private void InitializeBackgroundWorker()
    {
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
        backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
    }

    private void buttonParse_Click(object sender, EventArgs e)
    {
        DescriptionLabel.Visible = true;
        progressBar1.Visible = true;
        backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {

        BackgroundWorker worker = sender as BackgroundWorker;
        Methods.ParsePerfusionData(backgroundWorker1); //Also tried using 'worker' here, but didnt work either
    }

我不能在这样的全局方法中使用backgroundworker吗?预先感谢!

2 个答案:

答案 0 :(得分:1)

i < amount时,i / amount * 100 = 0 * 100 = 0

只需使用i * 100 / amount即可。

还要确保backgroundWorker1.WorkerReportsProgress = true

答案 1 :(得分:0)

您只能报告不同操作之间的进度。这意味着:

  • 使用非常现代的类来支持此级别的报告。对于您的情况,此类类可能不存在。
  • 将代码的工程部分逆向循环至要进行报告的循环。通常,会在文件等上触发循环。

GUI更新必须包含在RunWorkerCompelted和ProgressReport事件中。并且,根据更新的频率,可能必须保留ProgressReport才能仅更新进度条。

这是我用BackgroundWorker编写的一些旧代码,应该可以帮助您入门:

#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
    if (!bgwPrim.IsBusy)
    {
        //Prepare ProgressBar and Textbox
        int temp = (int)nudPrim.Value;
        pgbPrim.Maximum = temp;
        tbPrim.Text = "";

        //Start processing
        bgwPrim.RunWorkerAsync(temp);
    }
}

private void btnPrimCancel_Click(object sender, EventArgs e)
{
    if (bgwPrim.IsBusy)
    {
        bgwPrim.CancelAsync();
    }
}

private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
    int highestToCheck = (int)e.Argument;
    //Get a reference to the BackgroundWorker running this code
    //for Progress Updates and Cancelation checking
    BackgroundWorker thisWorker = (BackgroundWorker)sender;

    //Create the list that stores the results and is returned by DoWork
    List<int> Primes = new List<int>();


    //Check all uneven numbers between 1 and whatever the user choose as upper limit
    for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
    {
        //Report progress
        thisWorker.ReportProgress(PrimeCandidate);
        bool isNoPrime = false;

        //Check if the Cancelation was requested during the last loop
        if (thisWorker.CancellationPending)
        {
            //Tell the Backgroundworker you are canceling and exit the for-loop
            e.Cancel = true;
            break;
        }

        //Determin if this is a Prime Number
        for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
        {
            if (PrimeCandidate % j == 0)
                isNoPrime = true;
        }

        if (!isNoPrime)
            Primes.Add(PrimeCandidate);
    }

    //Tell the progress bar you are finished
    thisWorker.ReportProgress(highestToCheck);

    //Save Return Value
    e.Result = Primes.ToArray();
}

private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    pgbPrim.Value = e.ProgressPercentage;
}

private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    pgbPrim.Value = pgbPrim.Maximum;
    this.Refresh();

    if (!e.Cancelled && e.Error == null)
    {
        //Show the Result
        int[] Primes = (int[])e.Result;

        StringBuilder sbOutput = new StringBuilder();

        foreach (int Prim in Primes)
        {
            sbOutput.Append(Prim.ToString() + Environment.NewLine);
        }

        tbPrim.Text = sbOutput.ToString();
    }
    else 
    {
        tbPrim.Text = "Operation canceled by user or Exception";
    }
}
#endregion