【问题标题】:How can I make all this code work under backgroundworker我怎样才能让所有这些代码在后台工作人员下工作
【发布时间】:2013-06-23 09:52:28
【问题描述】:

现在我有这个代码:

private void button1_Click(object sender, EventArgs e)  
{
  OpenFileDialog openFileDialog1 = new OpenFileDialog();

    var dialogResult = openFileDialog1.ShowDialog();
    string sWybranyPlik;
    if (dialogResult  == DialogResult.OK)
    {
      sWybranyPlik = openFileDialog1.FileName;

      try
      {


        System.Data.OleDb.OleDbConnection ExcelConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + sWybranyPlik + "';Extended Properties=Excel 8.0;"); 

        System.Data.OleDb.OleDbDataAdapter OleDBAdapter = new System.Data.OleDb.OleDbDataAdapter("select * from [Tabelle1$]", ExcelConnection);

        DtSet.Clear();


        //wypełnianie datagridview
        OleDBAdapter.Fill(DtSet.Tables[0]);
        dataGridView1.DataSource = DtSet.Tables[0];


        //kasowanie starych danych w bazie danych
        string deletesql = @"DELETE FROM TabelaProdukty";
        System.Data.SqlServerCe.SqlCeCommand comDelete = new System.Data.SqlServerCe.SqlCeCommand(deletesql, sqlconnection);
        sqlconnection.Open();
        comDelete.ExecuteNonQuery();
        sqlconnection.Close();


        backgroundWorker1.RunWorkerAsync(); 
        progressform.ShowDialog();



        ExcelConnection.Close();
      }

      catch (Exception ex)
      {
        MessageBox.Show(ex.ToString());
      }
    }
} 

在 _DoWork 中:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{

  //wprowadzanie nowych danych z datagridview do bazy danych
  string strQuery = @"INSERT INTO TabelaProdukty VALUES (@VD, @ItemCode, @Item, @Qty, @Ppcur, @StandardPrice, @CeMarked, @Description, @Description2, @Edma)";
  sqlconnection.Open();
  using (System.Data.SqlServerCe.SqlCeCommand comm = new System.Data.SqlServerCe.SqlCeCommand(strQuery, sqlconnection))
  {
    comm.Parameters.Add("@VD", SqlDbType.NVarChar);
    comm.Parameters.Add("@ItemCode", SqlDbType.NVarChar);
    comm.Parameters.Add("@Item", SqlDbType.NVarChar);
    comm.Parameters.Add("@Qty", SqlDbType.NVarChar);
    comm.Parameters.Add("@Ppcur", SqlDbType.NVarChar);
    comm.Parameters.Add("@StandardPrice", SqlDbType.NVarChar);
    comm.Parameters.Add("@CeMarked", SqlDbType.NVarChar);
    comm.Parameters.Add("@Description", SqlDbType.NVarChar);
    comm.Parameters.Add("@Description2", SqlDbType.NVarChar);
    comm.Parameters.Add("@Edma", SqlDbType.NVarChar);

    for (int i = 0; i < dataGridView1.Rows.Count; i++)
    {

      comm.Parameters["@VD"].Value = dataGridView1.Rows[i].Cells["VD"].Value.ToString().Trim();
      comm.Parameters["@ItemCode"].Value = dataGridView1.Rows[i].Cells["ItemCode"].Value.ToString().Trim();
      comm.Parameters["@Item"].Value = dataGridView1.Rows[i].Cells["ITEM"].Value.ToString().Trim();
      comm.Parameters["@Qty"].Value = dataGridView1.Rows[i].Cells["QUANTITY"].Value.ToString().Trim();
      comm.Parameters["@Ppcur"].Value = dataGridView1.Rows[i].Cells["PPCUR"].Value.ToString().Trim();
      comm.Parameters["@StandardPrice"].Value = dataGridView1.Rows[i].Cells["STANDARD_SELL_PRICE"].Value.ToString().Trim();
      comm.Parameters["@CeMarked"].Value = dataGridView1.Rows[i].Cells["CE-MARKED"].Value.ToString().Trim();
      comm.Parameters["@Description"].Value = dataGridView1.Rows[i].Cells["ITEM_DESCRIPTION"].Value.ToString().Trim();
      comm.Parameters["@Description2"].Value = dataGridView1.Rows[i].Cells["ITEM_DESCRIPTION2"].Value.ToString().Trim();
      comm.Parameters["@Edma"].Value = dataGridView1.Rows[i].Cells["EDMA"].Value.ToString().Trim();


      comm.ExecuteNonQuery();

      backgroundWorker1.ReportProgress(i);

      if (backgroundWorker1.CancellationPending)
      {
        e.Cancel = true;
        break;
      }

    }
    sqlconnection.Close();


  }
}

如您所见,此代码让我使用 OpenFileDialog 选择一个 excel 文件,清除 DataSet,用数据填充数据集和 datagridview,清除 SQL 表,然后打开一个带有进度条的表单,显示复制数据的漫长过程从 datagridview 到 sql 数据库(大约 12 列中的 150000 行。 此时它工作正常。我遇到的问题是打开progressform之前的一切也需要时间,所以我想把它全部放在backgroundworker下,并在progressform中显示状态报告,如“旧数据已删除”或表“正在加载新数据”,然后运行progressbar对于 dgv->sql 部分。不幸的是,通过将此代码放在 _DoWork 下,我会得到不同的错误,具体取决于我在那里复制了多少代码(所有 button1_Click 或仅“尝试”部分)。

你有什么想法吗?

最好的问候,

编辑:

其他方法:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{

  progressform.progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if (e.Cancelled)
  {
    MessageBox.Show("Operacja przerwana! Cennik nie został wprowadzony w całości", "Uwaga!", MessageBoxButtons.OK, MessageBoxIcon.Warning);


  }
  else
  {

    progressform.label1.Text = "Zakończono pomyślnie! :)";
    progressform.button1.Enabled = true;
  }
}

【问题讨论】:

    标签: c# sql datagridview progress-bar backgroundworker


    【解决方案1】:

    你需要使用backgroundworker的reportProgress事件。

    将来自openfiledialog 的文件名保存在实例级别的字符串中,即在方法之外。现在将用于填充dataset 的代码完全转移到backgroundworker.dowork 事件处理程序中。填充dataset 后调用backgroundworker.ReportProgress。这将触发backgroundworker.ProgressChanged 事件。在此方法中填充您的 datagridview,因为此方法将在实例化后台工作程序的线程上调用。现在在dowork 方法中发送其余的ADO 连接代码。应该够了。

    **EDIT**
    
    class YourClass
        {
            string filePath;
            DataSet dataset;
            private static void Do_Work(object sender, DoWorkEventArgs e)
            {
                //populate dataset
                //call worker.ReportProgress to trigger worker.ProgressChanged 
                //rest of time consuming ADO.Net Codes and other codes you wrote in your DoWork method
            }
    
            private static void Progress_Changed(object sender, ProgressChangedEventArgs e)
            {
                //this method is invoked in the thread where background worker is instantiated.
                //do all UI stuff here like populating datagridview from dataset
            }
        }
    

    【讨论】:

    • 谢谢,我正在努力解决这个问题(这并不容易,因为我只是在用 c# 启动)。不管怎样,你说我应该把填充数据集的代码放在reportprogress下。在加载到 sql 期间已调用此事件以使进度条工作。我应该如何知道 reportchanged 事件是否应该执行数据集或 sql 部分?一些if方法?或者也许我不明白你......(可能是这个;))
    • 你是否包含了progresschanged方法?
    • 谢谢,您的想法更清楚了,但仍然无法实现。我用参数0调用reportprogress,所以在progresschanged中我做了if (... == 0) {这里datagridview填充了datase}但是我得到一个默认的dgv错误,索引0没有值
    • 好的。我用谷歌搜索了更多。我了解到我必须在 _dowork 之外进行所有 UI 更改。所以我尝试将 dataset.clear 和 excel 文件加载到 progress_changed 事件。但它并没有像我希望的那样工作。问题有时是循环不工作(dgv->sql 循环)和进度条不能正常工作(停在一半或根本不动)。无论如何 +1 让我意识到这应该如何工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    相关资源
    最近更新 更多