C# 进度条未显示进度
我的程序上有一个进度条,我试图在处理完每个“数据表”后为它添加值,但它只在完成所有操作后更新 代码如下:C# 进度条未显示进度,c#,C#,我的程序上有一个进度条,我试图在处理完每个“数据表”后为它添加值,但它只在完成所有操作后更新 代码如下: int c = 0; OdbcConnection cn = openOdbcDB(); foreach(DataSet ds in allDataSets) { foreach(DataTable dt in ds.Tables) { foreach (DataRow dr in dt.Rows) { insertInt
int c = 0;
OdbcConnection cn = openOdbcDB();
foreach(DataSet ds in allDataSets)
{
foreach(DataTable dt in ds.Tables)
{
foreach (DataRow dr in dt.Rows)
{
insertIntoDatabaseCurrentRecord(dr);
}
}
pbMain.Value = pbMain.Value + (33 / totalFiles);
c++;
}
cn.Close();
cn.Dispose();
是否有一种方法可以强制条形图在每个表完成后显示进度,就像它完成一样?目前,我只看到循环完成后的进度,我看到行从空到满。每个DataTable大约有18000条记录,因此我应该能够看到它,因为它需要大约一分钟的时间来处理所有记录。假设所有这些都发生在UI线程中,那么它不会更新,因为您让线程忙于处理循环。您需要生成一个后台线程来进行处理,这样它就不会挂起您的UI线程。然后需要使用
control.Invoke
将实际设置进度条的部分推回到UI线程
请参见此处:对于线程示例(尽管有许多方法可以实现这一点)和
控制。调用假设所有这些都发生在UI线程中,那么它不会更新,因为您让线程忙于处理循环。您需要生成一个后台线程来进行处理,这样它就不会挂起您的UI线程。然后需要使用control.Invoke
将实际设置进度条的部分推回到UI线程
请参见此处:对于线程示例(尽管有许多方法可以实现)和Control.Invoke,由于循环正在阻止活动线程,因此必须使用另一个线程(干净方式)或仅在WinForms上使用Application.DoEvents():
int c = 0;
OdbcConnection cn = openOdbcDB();
foreach(DataSet ds in allDataSets)
{
foreach(DataTable dt in ds.Tables)
{
foreach (DataRow dr in dt.Rows)
{
insertIntoDatabaseCurrentRecord(dr);
Application.DoEvents(); //Quick and dirty
}
}
pbMain.Value = pbMain.Value + (33 / totalFiles);
c++;
}
cn.Close();
cn.Dispose();
由于您的循环正在阻止活动线程,因此您必须使用另一个线程(干净方式)或仅在WinForms上使用Application.DoEvents():
int c = 0;
OdbcConnection cn = openOdbcDB();
foreach(DataSet ds in allDataSets)
{
foreach(DataTable dt in ds.Tables)
{
foreach (DataRow dr in dt.Rows)
{
insertIntoDatabaseCurrentRecord(dr);
Application.DoEvents(); //Quick and dirty
}
}
pbMain.Value = pbMain.Value + (33 / totalFiles);
c++;
}
cn.Close();
cn.Dispose();
使用BackgroundWorker:
BackgroundWorker _worker;
// executes on another thread
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker)sender;
int c = 0;
OdbcConnection cn = openOdbcDB();
foreach (DataSet ds in allDataSets)
{
foreach (DataTable dt in ds.Tables)
{
foreach (DataRow dr in dt.Rows)
{
insertIntoDatabaseCurrentRecord(dr);
}
}
// do not update UI elements here, but in ProgressChanged event
//pbMain.Value = pbMain.Value + (33 / totalFiles);
c++;
worker.ReportProgress(c); // call ProgressChanged event of the worker and pass a value you can calculate the percentage from (I choose c, since it is the only calculated value here)
}
cn.Close();
cn.Dispose();
}
// gets called on your main thread
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// update the progressbar here.
// e.ProgressPercentage holds the value passed in DoWork.
}
使用BackgroundWorker:
BackgroundWorker _worker;
// executes on another thread
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker)sender;
int c = 0;
OdbcConnection cn = openOdbcDB();
foreach (DataSet ds in allDataSets)
{
foreach (DataTable dt in ds.Tables)
{
foreach (DataRow dr in dt.Rows)
{
insertIntoDatabaseCurrentRecord(dr);
}
}
// do not update UI elements here, but in ProgressChanged event
//pbMain.Value = pbMain.Value + (33 / totalFiles);
c++;
worker.ReportProgress(c); // call ProgressChanged event of the worker and pass a value you can calculate the percentage from (I choose c, since it is the only calculated value here)
}
cn.Close();
cn.Dispose();
}
// gets called on your main thread
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// update the progressbar here.
// e.ProgressPercentage holds the value passed in DoWork.
}
在此线程上使用Thread
?你能给我举个例子吗?或者Application.DoEvents(),如果它是表单应用程序。(Quick&dirty)或BackgroundWorker ReportsProgress这是一个表单应用程序,而不是web表单,只是一个很好的普通c#在这个线程上使用线程
。线程?你能给我举个例子吗?或者Application.DoEvents(),如果它是表单应用程序。(Quick&dirty)或BackgroundWorker ReportsProgress它是一个表单应用程序,而不是web表单,只是一个很好的普通c#Ugh。请使用后台线程,不要使用Application.DoEvents
。我认为pbMain.Refresh()
够了吗?@MattBurland我同意你的看法,但如果他只是想看到一个快速的结果,他可以使用DoEvents(),但一定要看一看线程。这不是一种快速而肮脏的方式。“你可以这样做,但这是错误的方式,你不应该这样做。”这没有帮助。他需要知道如何正确地做,而不是如何不正确地做。呃。请使用后台线程,不要使用Application.DoEvents
。我想pbMain.Refresh()
够了吗?@MattBurland我同意你的看法,但如果他只是想看到一个快速的结果,他可以使用DoEvents(),但一定要看一看Threads。这不是一种快速肮脏的方式。“这是你可以做到的,但这是一种错误的方式,你不应该这样做。“那没用。他需要知道如何正确地做,而不是如何不正确地做。