在BackgroundWorker中,只有2个进度条中的1个得到更新

时间:2012-10-25 10:10:46

标签: c# .net winforms backgroundworker

我有一个简单的表单,上面有2个progressbars和1个​​backgroundworker。我有2个循环(一个在另一个循环中),我想报告每个循环的进度一旦递增。这是我的代码:

private void buttonStart_Click(object sender, EventArgs e)
{
    workerCustomers.RunWorkerAsync();
}

private void workerCustomers_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
    progressBar2.Value = (int)e.UserState;
}

private void workerCustomers_DoWork(object sender, DoWorkEventArgs e)
{
    for (int customer = 0; customer < 50; customer++)
    {
        int customerPercentage = ++customer * 100 / 50;
        workerCustomers.ReportProgress(customerPercentage, 0);

        for (int location = 0; location < 500; location++)
        {
            int locationPercentage = ++location * 100 / 500;
            workerCustomers.ReportProgress(customerPercentage, locationPercentage);
        }

        workerCustomers.ReportProgress(customerPercentage, 0);
    }
}

当程序运行时,progressbar1会更新得很好,但progressbar2永远不会移动。如果我通过调试器运行它,我可以看到progressbar2的值被更改,没有图形化的更改。有什么想法吗?

3 个答案:

答案 0 :(得分:5)

是的,如果您在桌面上启用了Aero,则第二个进度条将无法更新。它提供了动画进度条,默认情况下为绿色,带有旅行高亮音符。

此进度条样式很特殊,它会插入中间值并始终看起来很平滑,即使您将课程值分配给Value属性也是如此。换句话说,您可以分配10,20,30等等,但是栏不会跳转。它可以平滑地增加条长。

这有副作用。要使此动画生效,进度条必须滞后。换句话说,它始终显示的值落后编程值。并且必须经过一段时间才能将条形长度平滑地增加到编程值。

您需要了解的另一个细节:当您减少 Value属性时,此动画会,会立即跳过条形长度。

所以问题是你以非常高的速率更新Value属性,比bar可以插入的速度快得多。它永远无法赶上。除非您在0处重新启动,否则会立即跳转到该栏。速度非常高,动画永远无法达到1。

您可以通过在内部循环中插入此语句来看到这一点:

   System.Threading.Thread.Sleep(1);

使用参数值进行游戏,您可能需要将其增加到16才能看到任何差异。你做得越高,通过插值使得它越远。

这当然不是一个真正的问题,这是因为你的工人没有做任何实际的工作。一旦你开始编写这个BGW应该执行的真实代码,那么你也会降低调用ProgressChanged的速率。

答案 1 :(得分:1)

问题在于你的内循环太紧,以至于gui更新过于频繁地发布,以便gui准确地响应它们。解决方案是将您的实际工作添加到内部循环中,因此需要更长的时间,或者如果您想模拟GUI,您只需添加Thread.Sleep(100)来模拟工作需要一些时间。

同时确保将进度条最大值设置为100,因为这是您为每个进度条返回的最大值。

答案 2 :(得分:0)

你的主要问题来自过快的内循环,这意味着你无法真正看到进度,因为更新速度太快,无法进度条处理。

您的代码行:

location * 100 / 500 
完成内循环后,

将等于100,因此将进度条最大值设置为500与该数字无关。这意味着您的进度条永远不会达到最大值。

相关问题