C# BackgroundWorker中只有2个进度条中的1个得到更新

C# BackgroundWorker中只有2个进度条中的1个得到更新,c#,.net,winforms,backgroundworker,C#,.net,Winforms,Backgroundworker,我有一个简单的表单,上面有两个进度条和一个backgroundworker。我有两个循环(一个循环在另一个循环中),每次循环递增后,我都要报告每个循环的进度。以下是我的代码: private void buttonStart_Click(object sender, EventArgs e) { workerCustomers.RunWorkerAsync(); } private void workerCustomers_ProgressChanged(object sender,

我有一个简单的表单,上面有两个进度条和一个backgroundworker。我有两个循环(一个循环在另一个循环中),每次循环递增后,我都要报告每个循环的进度。以下是我的代码:

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);
    }
}
private void按钮开始单击(对象发送者,事件参数e)
{
workerCustomers.RunWorkerAsync();
}
private void workerCustomers\u ProgressChanged(对象发送方,ProgressChangedEventArgs e)
{
progressBar1.值=e.ProgressPercentage;
progressBar2.Value=(int)e.UserState;
}
私有void worker客户(对象发送方,DoWorkEventArgs e)
{
对于(int customer=0;customer<50;customer++)
{
int customerPercentage=++客户*100/50;
workerCustomers.ReportProgress(customerPercentage,0);
对于(int位置=0;位置<500;位置++)
{
内部位置百分比=++位置*100/500;
workerCustomers.ReportProgress(customerPercentage,locationPercentage);
}
workerCustomers.ReportProgress(customerPercentage,0);
}
}

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

问题在于,您的内部循环非常紧密,gui更新发布得太频繁,gui无法准确响应。解决方案是将实际工作添加到内部循环中,因此需要更长的时间,或者如果您想要模拟GUI,您可以添加一个
线程。Sleep(100)
,以模拟需要一些时间的工作


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

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

此进度条样式非常特殊,它插入中间值,并且始终看起来平滑,即使将课程值指定给“值”特性也是如此。换句话说,你可以指定10,20,30等等,但是这个条不会跳。它平滑地增加了杆的长度

这有副作用。要使此动画正常工作,进度条必须滞后。换句话说,它总是显示一个低于编程值的值。必须经过一段时间,才能顺利地将棒长度增加到编程值

您需要知道的另一个细节是:减少“值”属性时不会发生此动画,该属性会立即跳过条的长度

所以问题是,您正在以非常高的速率更新Value属性,比条插值的速度快得多。它永远赶不上。除非在0处重新启动,否则会立即跳出该条。速率如此之高,以至于动画永远无法达到1

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

   System.Threading.Thread.Sleep(1);
使用参数值,您可能需要将其增加到16才能看到任何差异。制作的越高,条通过插值制作的距离就越远


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

您的主要问题来自太快的内部循环,这意味着您实际上无法看到进度,因为更新太快,progressbar无法处理

您的代码行:

location * 100 / 500 

当您完成内部循环时,将等于100,因此将progressbar最大值设置为500与该数字不太相关。这意味着您的进度条永远不会达到最大值。

进度条的最大值设置正确吗?@lc.,是的,默认情况下,它设置为100,但我已将其更改为与第二个循环计数器总数500相匹配。500的循环速度会非常快。它可能只是看起来没有更新。尝试将Thread.Sleep()添加到内部循环中,看看它是否真的发生得太快而让您看不到。对,但是外部循环正在进行50*500次迭代。在一个紧循环中调用reportprogress,只需很少的工作,这可能会影响性能,因为返回主线程并引发事件需要花费大量的工作。首先,修复进度条的最大值,使其与最大值(100)相匹配。第二,要么将您的工作添加到内部循环,这样需要更多的时间,要么您可以通过添加线程来模拟它,以确保您的gui正常工作。Sleep(100),每个内部循环将有100毫秒的延迟谢谢您的详细回答,我学到了很多。那么,解决这个问题的最佳方法是什么呢?我在最后一段已经明确指出了这一点。这是解决这个问题的最佳答案。它解决了我的问题。谢谢向上投票。