2

I'm doing my first WinForms application featuring a background worker and progress bar. When I run my code it looks like the progress bar is delayed, because its animation -- approaching 100% -- is not completed when the code for the RunWorkerCompleted is executed. (A few hundred milliseconds the progress bar is filled.) Is there a way to make things more synchronized?

From a user perspective I'm expecting the progress bar to reach 100% before other things start to happen.

componentList.Count, below, is usually 5-15, meaning the progress animation jumps roughly 10-20% each increment.

My code:

    private void ExecuteButton_Click(object sender, EventArgs e)
    {
        ExecuteButton.Enabled = false;
        backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        int filesRun = 0;
        foreach(string file in componentList)
        {
            api.ExecuteInstructions(file);
            int progress = ++filesRun * 100 / componentList.Count;
            backgroundWorker1.ReportProgress(progress);
        }
    }

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

    void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        ExecuteButton.Enabled = true;
    }

My current workaround, giving the impression of simultaneousness:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        int filesRun = 0;
        foreach(string file in componentList)
        {
            api.ExecuteInstructions(file);
            int progress = ++filesRun * 100 / componentList.Count;
            if(progress == 100)
                progress--;

            backgroundWorker1.ReportProgress(progress);
        }

        Thread.Sleep(650); // cosmetic paus
        backgroundWorker1.ReportProgress(100);
    }

UPDATE:

Using the trick suggested in the question "Disabling .NET progressbar animation when changing value?" I managed to solve my problem by using the existing implementation and then adding the following logic:

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

        if (e.ProgressPercentage == 100)
        {
            progressBar1.Value = 101;
            progressBar1.Maximum = 100;
            progressBar1.Value = 100;
        }
    }
matpe
  • 284
  • 4
  • 13

1 Answers1

0

Do a simple trick, instead of solving the UI thread synchronization problem. Simply set progress bar to 100% in _RunWorkerCompleted.

void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  progressBar1.Value = 100;
  Application.DoEvents();
  ExecuteButton.Enabled = false;
}
Marko Juvančič
  • 5,792
  • 1
  • 25
  • 41
  • Sadly, that didn't do the trick. Setting progressBar1.Value = 100 still requires the animation to run. Updating the Value property will only take a few cycles, and it's not enough to have it reach 100%. – matpe Jan 02 '16 at 20:59