方法中通过backgroundworker更新进度条

Updating progressbar through backgroundworker in method

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

不幸的是,我无法让它工作,因为进度条根本不更新,一直是空的。

这是我目前的情况:

        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
    }

在方法中它看起来像这样:

    public static void ParsePerfusionData(BackgroundWorker worker)
    {
            for (int i = 2; i < Globals.DataList.Count; i++)
        {

                worker.ReportProgress(i / amount * 100);
                rest of the code etc.
        }
    }

我不能在这样的全局方法中使用后台程序吗?提前致谢!

i < amounti / amount * 100 = 0 * 100 = 0

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

还要确保 backgroundWorker1.WorkerReportsProgress = true

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

  • 使用支持此级别报告的非常现代的 class。您的情况可能不存在这样的 class。
  • 将部分代码逆向工程到您要报告的循环。通常是遍历文件等的循环。

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