【问题标题】:Updating progressbar through backgroundworker in method通过方法中的backgroundworker更新进度条
【发布时间】:2019-05-04 21:15:38
【问题描述】:

我的程序(在 C# 中使用 Windows 窗体)正在读取和解析大量数据,我正在使用调用这些全局方法(读取和解析)的 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.
        }
    }

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

【问题讨论】:

标签: c# winforms methods progress-bar backgroundworker


【解决方案1】:

i &lt; amount 然后i / amount * 100 = 0 * 100 = 0

只需改用i * 100 / amount

还要确保backgroundWorker1.WorkerReportsProgress = true

【讨论】:

  • 哇哦,这也有效。如果你不介意,为什么 i/amount(amount 是正在解析的列表的大小)总是等于 0?它是否会将 0 以下的数字四舍五入,或者为什么这不起作用?
  • 整数除法:5/2 = 2,2/5=0
  • 哦,我明白了。谢谢!
【解决方案2】:

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

  • 使用支持此级别报告的非常现代的类。您的情况可能不存在这样的类。
  • 将代码的部分逆向工程,直至您想要生成报告的循环。通常是迭代文件等的循环。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多