为什么 RunWorkerCompletedEventArgs 事件在我完成整个进度条加载之前启动?

Why is the event RunWorkerCompletedEventArgs launched before I finished loading the progress bar in its entirety?

当我 运行 一项繁重的任务或一些数据时,在任务结束时 label 显示的百分比正确地达到 100% 并显示 finalized message,但即使 progressBar 还没有完全加载,当显示完成消息时,您可以看到完成工作的进度条动画。

我没能解决这个问题,进度条应该像我见过的所有系统一样自然地工作,进度完成然后显示完成消息。


这里我举个例子:

BackgroundWorker bg = new BackgroundWorker();

private void btnRun_Click(object sender, EventArgs e)
{
    bg.WorkerReportsProgress = true;
    bg.ProgressChanged += bg_ProgressChanged;
    bg.DoWork += bg_DoWork;
    bg.RunWorkerCompleted += bg_RunWorkerCompleted;
    bg.RunWorkerAsync();
    label1.Visible = true;
    progressBar1.Visible = true;
}

Dowork 事件:

private void bg_DoWork(object sender, DoWorkEventArgs e)
{
    int progress = 0, percent = 0; 
    for (int i = 0; i < ds.Tables[0].Rows.Count; i++) //Cycle that will represent the heavy task
    {
        totalRecords = ds.Tables[0].Rows.Count; 

        progress++;
        percent = Convert.ToInt16((((double)progress / (double)totalRecords ) * 100.00)); 
        System.Threading.Thread.Sleep(500);
        bg.ReportProgress(percent );
    }
}

进度已更改

private void bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // Change the value of the ProgressBar to the BackgroundWorker progress.
    progressBar1.Step = 1;
    progressBar1.Style = ProgressBarStyle.Continuous;
    progressBar1.Minimum = 0;
    progressBar1.Maximum = 100;

    if (e.ProgressPercentage > 100)
    {
        label1.Text = "100%";
        progressBar1.Value = progressBar1.Maximum;
    }
    else
    {
        label1.Text = Convert.ToString(e.ProgressPercentage) + "%";
        progressBar1.Value = e.ProgressPercentage;
    }
}

最后,当 BackgroundWorker 完成时执行的 RunWorkerCompleted 事件:

private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    MessageBox.Show("Done...");
    label1.Visible = false;
    progressBar1.Visible = false;
}

如何解决这个进度条动画问题?

环境: Visual Studio 2010 (WindowsForms) & .NET NetFramework 4.

我认为您正面临 Windows 航空动画的经典问题。
this page 中提取的信息。

进度条递增时会出现此延迟。但是当进度条递减.

时不会发生

所以基本上,您要做的是移动过去您应该达到的实际值,然后递减到实际值。

页面作者使用了扩展方法,您也可以随意使用;我只是把相关代码放在这里:

// To get around the progressive animation, we need to move the 
// progress bar backwards.
if (value == pb.Maximum)
{
    // Special case as value can't be set greater than Maximum.
    pb.Maximum = value + 1;     // Temporarily increase Maximum
    pb.Value = value + 1;       // Move past
    pb.Maximum = value;         // Reset maximum
}
else
{
    pb.Value = value + 1;       // Move past
}
pb.Value = value;