我有一个简单的表单,上面有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的值被更改,没有图形化的更改。有什么想法吗?
答案 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与该数字无关。这意味着您的进度条永远不会达到最大值。