Fill dataGridView thank's to backGroundWorker

独自空忆成欢 提交于 2020-01-13 10:05:31

问题


I have this code snippet:

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        remplirDataGrid();
    }

private void frmChercherActesLoad(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();

        }



 private void remplirDataGrid()
        {
            dataGridView1.DataSource = ActeServices.getAllActes(0, 40);
            dataGridView1.Columns[0].Visible = false;
            dataGridView1.Columns[1].HeaderText = "Code acte";
            dataGridView1.Columns[2].HeaderText = "Désignation";
            dataGridView1.Columns[3].HeaderText = "Pris en charge";
            dataGridView1.Columns[4].HeaderText = "Id article";
            dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
        }

And here is the method getAllActe:

public static IEnumerable<Acte> getAllActes(int skipCount, int takeCount)
        {
            var myTableAdapter = new SmartDocDALServices.SmartDocDataSetTableAdapters.actesTableAdapter();
            myTableAdapter.Fill(myDataSet.actes);
            var myResult = from q in myDataSet.actes.AsEnumerable()
                            select new Acte
                            {
                                code = q.code,
                                designation = q.designation,
                                priseEnCharge = q.prise_en_charge,
                                idArticle = q.id_article,
                            };

            if (skipCount != -1)
                myResult.Skip(skipCount);
            if (takeCount != -1)
                myResult.Take(takeCount);
            IEnumerable<Acte> myResultRet = myResult.ToList();
            return myResultRet;

What I like to do is to fill my datagridview using the background worker once I run the application I got this error:

Inter-thread operation not valid: Control 'dataGridView1 has been the subject of an access from a thread other than the one it was created.


I try this

 private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
      IEnumerable<Acte> result = ActeServices.getAllActes(0, 40);
       backgroundWorker1.ReportProgress(0, result);

    }

    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

      dataGridView1.DataSource = (IEnumerable<Acte>)e.UserState;
      dataGridView1.Columns[0].Visible = false;
      dataGridView1.Columns[1].HeaderText = "Code acte";
     ***

but nothing gained in time?. I'd like that the datagrid update when the BGW loads data foreash data load it add it to the DGV


回答1:


You can't update the UI from a BackgroundWorker thread.

You need to send an event to the UI and then have something like:

private void EventHandler(object sender, YourEventArgs e)
{
    if (this.dataGridView1.InvokeRequired)
    {
        this.dataGridView1.Invoke((MethodInvoker)delegate { this.AddToGrid(e.YourData); });
    }
    else
    {
        this.AddToGrid(e.YourData);
    }
}



回答2:


The DataGridView is not thread safe. However, setting the DataSource if the data is already available should be fast enough.

I would recommend:

  1. Only use your BackgroundWorker to load the data in another thread

  2. Set the DataSource and the other modifications of the datagridview in the RunWorkerCompleted Event (you can pass the result from the DoWork method to the Completed event by setting

    e.Result = ActeServices.getAllActes(0, 40);

  3. Optional: Set dataGridView1.AutoGenerateColumns to false and manually add the columns either in the Windows Forms Designer or in code to avoid flicker.




回答3:


It is because GUI stuff cannot be modified from other threads than the GUI thread. To fix this, you need to invoke the changes on the GUI thread by using the Dispatcher.

The DataGrid should be setup beforehand, so all you do in your async operation is fill the data.

var data = ActeServices.getAllActes(0, 40);

Dispatcher.BeginInvoke( new Action( () => { dataGridView1.DataSource = data; }))



回答4:


The BackgroundWorker class was designed to run a long-standing operation on a background thread. Since you are only allowed to access UI components from the thread that created them, you can use the RunWorkerCompleted event of the BackgroundWorker class to update your UI once your DoWork handler has completed. Also, you can safely update a progress UI using the ProgressChanged event of the BackgroundWorker class.



来源:https://stackoverflow.com/questions/3127838/fill-datagridview-thanks-to-backgroundworker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!