日期:2014-05-17  浏览次数:20926 次

关于BulkCopy和ProgressBar互动的问题!
大家好,

本人写了个导入Excel到SQL数据库的程序。为了让用户知道导入进度,我用了进度条显示导入进度。

 private void 导入_Click(object sender, EventArgs e)
{
//获取数据量
this.progressBar1.Maximum = Total;//设置进度条最大值为数据量
bkWorker.RunWorkerAsync();//激活Dowork事件
}

 public void DoWork(object sender, DoWorkEventArgs e)
{
.......
 using (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy(connectionString))
bcp.BatchSize = Total/100;
bcp.NotifyAfter = Total / 100;
bcp.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied);
bcp.DestinationTableName = "test";
bcp.WriteToServer(Table);//利用BulkCopy将table中的数据添加到test表中

}

        void bcp_SqlRowsCopied(object sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e) //响应上面的bcp.SqlRowsCopied
        {
            Done = Done + Total/100;
            bkWorker.ReportProgress(Done);
        }

 public void ProgessChanged(object sender, ProgressChangedEventArgs e)
 {
this.progressBar1.Value = e.ProgressPercentage;//实时更新进度条的值

this.label2.Text = e.ProgressPercentage.ToString();//用label显示进度条的值

 this.label1.Text = Convert.ToString(((e.ProgressPercentage) * 100 / progressBar1.Maximum)) + "%";//计算进度条比例,用label显示出来

 }

 public void CompleteWork(object sender, RunWorkerCompletedEventArgs e)
{
   this.label1.Text = "完成!";
}

我的想法是,在用BulkCopy的时候,每次进行操作的数据量是数据总量(Total)除以100,并将这个数值进行累加(Done)传递给进度条的value,这样进度条就会1%的累加,直至100%。

但是实际情况有时是这样的(尤其是数据量较大的时候),我的label2最终显示的值与真实的最大值有一个差值,这就导致我的进度条会没有走满就“完成”了。

所以我的问题就是:我不想把BulkCopy的BatchSize写死(比如固定在100或者1000),并且保证不出现进度条没有走满就显示“完成”的情况(label显示)。

谢谢大家。

我进行了4次测试,结果如下:
数据量(total=65535)|label2=65500;
数据量(total=131070)|label2=131000;
数据量(total=720885)|label2=713592;(进度条没有走满)
数据量(total=851955)|label2=775229;(进度条没有走满)