Обновление ProgressBar через backgroundworker в методе - PullRequest
0 голосов
/ 03 декабря 2018

Моя программа (в 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.
        }
    }

Могу ли я не использовать фонового работника в таком глобальном методе?Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Вы можете только сообщить о прогрессе между различными операциями.Это означает либо:

  • с использованием очень современного класса, поддерживающего этот уровень отчетности.Такая классификация может не существовать для вашего случая.
  • Обратный инжиниринг частей кода вплоть до цикла, по которому вы хотите создавать отчеты.Обычно цикл, который перебирает файлы и т. П.

Обновления 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
0 голосов
/ 03 декабря 2018

Когда i < amount, то i / amount * 100 = 0 * 100 = 0.

Просто используйте i * 100 / amount вместо.

Также убедитесь, что backgroundWorker1.WorkerReportsProgress = true

...