为什么进度条更新延迟`?

时间:2021-05-11 11:05:22

标签: c# winforms progress-bar

在这个简单的测试程序中,我想看到文本“完成!”在进度条被 100% 填满后。目前,它显示“完成!”在 100% 之前的方式 - 我什至能够获得它的屏幕截图。我猜,这个问题与 Windows 的消息队列有关,但即使是在设置标签之前的“Application.DoEvents()”也不能解决问题。 “Thread.Sleep(500)”将使问题消失,但它也会浪费我生命中的半秒;-) 我想知道为什么文本会在达到 100% 之前出现以及我能做什么(更好而不是睡觉)来避免它?

    private void button1_Click(object sender, EventArgs e)
    {
        button1.Enabled = false;
        label1.Text = "In progress";
        label1.Refresh();
        int CountDown = 10000;
        progressBar1.Value = 0;
        progressBar1.Maximum = CountDown;
        while  (CountDown > 0)
        {
            CountDown--;
            progressBar1.Value = progressBar1.Maximum - CountDown;
            progressBar1.Refresh();
        }
        label1.Text = "DONE!";
        button1.Enabled = true;
    }

进度条尚未完成,但“完成!”已经显示:

Progress bar not complete yet, but "DONE!" already displayed

受 Alexandru 和 Jimi 启发的 2.0 版更新(见下面的评论)

public partial class Form1 : Form
{
    const int cStartCountDown = 1000;

    public Form1()
    {
        InitializeComponent();
        backgroundWorker1.WorkerReportsProgress = true;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        progressBar1.Value = 0;
        progressBar1.Maximum = cStartCountDown;
        label1.Text = "In progress";
        label1.Refresh();
        if (backgroundWorker1.IsBusy != true)
            backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        int CountDown = cStartCountDown;
        while (CountDown > 0)
        {
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                CountDown--;
                worker.ReportProgress(CountDown);
            }
        }
    }
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = progressBar1.Maximum - e.ProgressPercentage;
        // progressBar1.Refresh();
        Task wait = Task.Delay(1);
        wait.Wait();
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            label1.Text = "Error: " + e.Error.Message;
        }
        else
        {
            label1.Text = "DONE!";
        }
    }
}

0 个答案:

没有答案