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

Rob*_*ert 5 .net c# backgroundworker winforms

我有一个简单的表单,上面有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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Han*_*ant 5

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

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

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

一个细节你需要知道:这部动画并没有当你碰巧降低 Value属性,立即跳杆的长度.

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

您可以通过在内部循环中插入此语句来查看:

   System.Threading.Thread.Sleep(1);
Run Code Online (Sandbox Code Playgroud)

使用参数值进行播放,您可能需要将其增加到16才能看到任何差异.你做得越高,条形通过插值越远.

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

  • 我在最后一段明确指出了这一点。 (2认同)