使用C#中的backgroundworker在datagridview中获取数据库数据

时间:2017-07-03 09:29:37

标签: c# datagridview

在datagridview中从数据库获取数据后,重复上一次数据,但错过了datagridview中的第一个数据。我点这个链接SelectMany

     private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        RetriveTableData Obj = (RetriveTableData)e.Argument;

        string SqlcmdString = "SELECT * from tblBook";

        SqlDataReader reader;
        int i = 1;
        try
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                Sqlcmd = new SqlCommand(SqlcmdString, conn);
                conn.Open();
                reader = Sqlcmd.ExecuteReader();

                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        //int.Parse(reader["NO_IND"].ToString());
                      //  Obj.EmpId = reader["C_FICH"].ToString();
                     //   Obj.EmpName = reader["C_SITE"].ToString();
                        Obj.AccessionNo = reader["accessionNo"].ToString();
                        Obj.Author = reader["author"].ToString();

                        Thread.Sleep(100);
                        // To Report progress.
                        backgroundWorker1.ReportProgress(i, Obj);

                        if (backgroundWorker1.CancellationPending)
                        {
                            // Set the e.Cancel flag so that the WorkerCompleted event
                            // knows that the process was cancelled.
                            e.Cancel = true;
                            backgroundWorker1.ReportProgress(0);
                            return;
                        }
                        i++;
                    }
                    conn.Close();
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    public class RetriveTableData
    {
        public string AccessionNo;
        public string Author;
    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        if (!backgroundWorker1.CancellationPending)
        {
            //Gets the user state that is sent as part of ReportProgress() Method from DoWork Event 
            RetriveTableData Obj = (RetriveTableData)e.UserState;
            //Add the data to the dataGridView1
            dataGridView1.Rows.Add(Obj.AccessionNo.ToString(), Obj.Author.ToString());
           progressBar1.Value = e.ProgressPercentage;
           label1.Text = "Processing row.. " + e.ProgressPercentage.ToString() + " of " + TotalRecords;
        }

    }
    private int GetTotalRecords()
    {
        SqlConnection con;
        SqlCommand cmd;
        try
        {
            using (con = new SqlConnection(connectionString))
            {
                cmd = new SqlCommand("SELECT COUNT(*) FROM tblBook", con);
                con.Open();
                TotalRecords = int.Parse(cmd.ExecuteScalar().ToString());
                con.Close();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        return TotalRecords;
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {

        if (e.Cancelled)
        {
            label1.Text = "Cancelled by User Intentionally...";
         progressBar1.Value = 0;
        }
        // Check to see if an error occurred in the background process. 
        else if (e.Error != null)
        {
           label1.Text = e.Error.Message;
        }
        else
        {
            // BackGround Task Completed with out Error
           label1.Text = " All Records Loaded...";
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // statusStrip1.Visible = true;
        // toolStripStatusLabel1.Visible = true;


        dataGridView1.ColumnCount = 2;
        dataGridView1.Columns[0].Name = "Access No.";
        dataGridView1.Columns[0].Width = 150;
        dataGridView1.Columns[1].Width = 150;
        dataGridView1.RowHeadersWidth = 21;
        dataGridView1.ColumnHeadersHeightSizeMode =  DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
        dataGridView1.ColumnHeadersHeight = 23;
        dataGridView1.Columns[1].Name = "Author";


        progressBar1.Maximum = GetTotalRecords();

        if (!backgroundWorker1.IsBusy)
        {
            RetriveTableData TObj = new RetriveTableData();
            dataGridView1.Rows.Clear();
            // Start the BackGround Thread to Execute
            backgroundWorker1.RunWorkerAsync(TObj);
          //  btStart.Enabled = false;
            //btCancel.Enabled = true;
        }

    }

我得到了这个输出,其中第一个数据:1122被遗漏,最后一个数据PEC-5281被重复。由于我的低级别我无法发布图像所以我把链接放在你可以查看输出。

https://www.mindstick.com/Articles/1148/datagrid-using-backgroundworker-c-sharp

1 个答案:

答案 0 :(得分:0)

您需要为每一行创建一个对象集合,然后将该集合用作DataGridView的数据源

使用async-await可以更清楚地完成投标,并且无需BackgroundWorker

创建的额外线程
 private async Task<IEnumerable<RetriveTableData>> GetDataAsync()
 {
    var query = "SELECT * from tblBook";
    using (var connection = new SqlConnection(connectionString))
    using (var command = new SqlCommand(query, connection))
    {
        await connection.OpenAsync();
        using (var reader = command.ExecuteReaderAsync())
        {
            var data = new List<RetriveTableData>();
            while(await reader.ReadAsync())
            {
                var temp = new RetriveTableData
                {
                    EmpId = reader["C_FICH"].ToString();
                    EmpName = reader["C_SITE"].ToString();
                    AccessionNo = reader["accessionNo"].ToString();
                    Obj.Author = reader["author"].ToString();
                };

                data.Add(temp);
            }

            return data;
        }
    }
}

然后例如在Form.Load eventhandler中,您可以加载数据。

private async void Form_Load(object sender, EventArgs e)
{
    dataGridView1.DataSource = await GetDataAsync();
}