The RunWorkerCompleted is triggered before the progressbar reaches 100% [duplicate]

心不动则不痛 提交于 2019-12-11 00:07:49

问题


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;
        }
    }

回答1:


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;
}


来源:https://stackoverflow.com/questions/34570486/the-runworkercompleted-is-triggered-before-the-progressbar-reaches-100

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!