Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 进度条未显示进度_C# - Fatal编程技术网

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。这不是一种快速肮脏的方式。“这是你可以做到的,但这是一种错误的方式,你不应该这样做。“那没用。他需要知道如何正确地做,而不是如何不正确地做。