我有一个Windows程序正在对数据库进行一些更新。它有2个循环,我想展示进展。第一个循环获取Customers列表,第二个循环获取该客户的位置列表:
DataTable dtCustomers = GetAllCustomers();
foreach(DataRow customer in dtCustomers.Rows)
{
//update Customer Progressbar...
//do some updating here...
DataTable dtLocations = GetAllLocations(customer);
foreach(DataRow location in dtLocations.Rows)
{
//do some updating here...
//update Location Progressbar...
}
//reset Location Progressbar...
}
所以我想做的是显示每个循环的可视进度条(pb)。客户pb将随每个已处理的客户递增,因此位置pb ...唯一的区别是pb将在每个位置后重置的位置,因为根据位置更新可能需要更长/更短。
我从1个后台工作人员开始,能够更新客户pb就好了。我将以下代码放在“开始”按钮中:
private void buttonStart_Click(object sender, EventArgs e)
{
workerCustomers.RunWorkerAsync();
}
并且在workerCustomer的DoWork()事件中,我放了2个循环。我知道位置pb不会更新,因为它会给出“交叉线程引用”错误。那么我该如何去做我想做的事呢?我甚至试图在表格上放两个bg工人,然后从另一个工作人员打电话给另一个工作人员,但同样,另一个错误说明第一个工人正忙着。
答案 0 :(得分:4)
报告进度时,您可以将其他userState对象作为第二个参数传递(请参阅ReportProgress方法定义):
workerCustomers.ReportProgress(percentage1, percentage2);
在ProgressChanged
事件处理程序中,您可以更新progressBars:
void workerCustomers_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage; // Customers
progressBar2.Value = (int)e.UserState; // Locations
}
更新:如何在您的案例中使用它
DataTable dtCustomers = GetAllCustomers();
int customerIndex = 0;
foreach(DataRow customer in dtCustomers.Rows)
{
//do some updating here...
int customerPercentage = ++customerIndex * 100 / dtCustomers.Rows.Count;
workerCustomers.ReportProgress(customerPercentage, 0);
int locationIndex = 0;
DataTable dtLocations = GetAllLocations(customer);
foreach(DataRow location in dtLocations.Rows)
{
//do some updating here...
int locationPecentage = ++locationIndex * 100 / dtLocations.Rows.Count;
workerCustomers.ReportProgress(customerPercentage, locationPecentage);
}
workerCustomers.ReportProgress(customerPercentage, 0);
}