C#Progress Bar未显示进度

时间:2013-08-13 13:15:42

标签: c#

我的程序上有一个进度条,我试图在每个“DataTable”处理完毕后为它添加值,但只有在完成所有操作后才会更新。

这是代码:

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条记录,所以我应该可以看到它,因为它需要大约一分钟来处理所有记录。

3 个答案:

答案 0 :(得分:4)

假设所有这一切都发生在UI线程中,那么它就不会更新,因为你让线程忙于处理你的循环。您需要生成后台线程来进行处理,以便它不会挂起您的UI线程。然后,您需要使用Contol.Invoke将实际设置进度条的部分推回到UI线程。

请参阅此处:http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx以获取线程示例(尽管有很多方法可以执行此操作)和Control.Invoke

答案 1 :(得分:1)

使用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.
}

答案 2 :(得分:0)

由于你的循环阻塞了活动线程,你必须使用另一个Thread(干净的方式)或者只是在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();