Home > Software engineering >  How to fix the error: the 'dataGridView1' control was accessed from a different thread [du
How to fix the error: the 'dataGridView1' control was accessed from a different thread [du

Time:10-05

Good morning everyone, I'm having trouble with rewriting a DataGrid, the function works, but I would need to do a faster search, so the thought was to add parallelism.

But upon applying the latter it generates an error for me: System.InvalidOperationException: 'Invalid cross-thread operation: the control 'dataGridView1' was accessed from a different thread than the one from which the creation was performed.'

The problem is clear to me, however I can't figure out how to solve it. Could you guys please help me out?

I've already tried applying Invoke but the program goes into an infinite loop.

private void inputSearch_TextChanged(object sender, EventArgs e)
    {
        Parallel.For(0, 7, i =>
        {
            Ricerca(i);
        });
    }

private void Ricerca(int i)
    {
        string searchValue = inputSearch.Text.ToUpper();
  
        var re = from row in dataTable.AsEnumerable()
                 where
                 row[i].ToString().Contains(searchValue)
                 select row;
        if (re.Count() != 0)
        {
            Invoke(new Action(() =>
            {
                dataGridView1.DataSource = re.CopyToDataTable();
                dataGridView1.Columns[7].Visible = false;
            }));

            
        }
    }

CodePudding user response:

You have a deadlock because you are blocking the UI thread in inputSearch_TextChanged method (that is invoked by UI thread).

If your intent is to parallelize the Linq expression, split Ricerca method in two. The final part of the method should be invoked out of the parallel for, maybe directly on inputSearch_TextChanged.

A better solution could be to use .NET Task instead.

Otherwise, if you don't need parallel at all, you can replace it with a simple for.

CodePudding user response:

I was able to solve the problem as suggested by Cherry by saving the content in another table and recopying it later.

private void inputSearch_TextChanged(object sender, EventArgs e)
    {
        Parallel.For(0, 7, i =>
        {
            Ricerca(i);
        });
        dataGridView1.DataSource = table;
        dataGridView1.Columns[7].Visible = false;
    }

    private void Ricerca(int i)
    {
        string searchValue = inputSearch.Text.ToUpper();

        var re = from row in dataTable.AsEnumerable()
                 where
                 row[i].ToString().Contains(searchValue)
                 select row;
        if (re.Count() != 0)
        {
            table = re.CopyToDataTable();
        }
    }

Thanks to all!

  • Related