2

I created 2 data grid view on the form application. I filled both of the columns 0 to 100. I want to fill both of grid view's raws at the same time. In order to make filling raws I created two threads and I used Invoke methods to solve cross thread exception ;

public void thread1()
    {        dataGridView1.BeginInvoke(new Action(delegate ()
        {
            a = 0;

            dataGridView1.Rows.Add(20);
            for (int i = 0; i < 100; i++)
            {
                dataGridView1.Rows[a].Cells[0].Value = i;
                dataGridView1.Rows[a].Cells[1].Value = i + 1;
                dataGridView1.Rows[a].Cells[2].Value = i + 2;
                dataGridView1.Rows[a].Cells[3].Value = i + 3;
                dataGridView1.Rows[a].Cells[4].Value = i + 4;

                if (i % 5 == 0) { a++; }
                dataGridView1.Refresh();
            }
        }));

    }

But when I call the threads on the main program with Parallel.Invoke or Task Parallel Library data grid views value's fillings working sequantial.

I wonder how can I make them parallelize??

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
snur
  • 23
  • 1
  • 3
  • You may want to take a look at [this post](https://stackoverflow.com/questions/487661/how-do-i-suspend-painting-for-a-control-and-its-children) to improve even more the performance of your DataGridView. I've achieved huge performance boosts with some standard Windows Forms controls using this solution. – sɐunıɔןɐqɐp Oct 21 '17 at 13:52

1 Answers1

1

You should not put time-consuming tasks in Control.Invoke code blocks because it will run in UI thread and makes the UI thread busy and makes your threading useless. So just put UI-reladet code in Invoke action.

You can use Task.Run to fill each DataGridView this way:

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
        //Define DataTable
        var table = new DataTable();
        table.Columns.Add("Column 1", typeof(int));

        //Fill DataTable
        for (int i = 0; i < 100000; i++)
            table.Rows.Add(new object[] { i });

        //Set DataSource
        dataGridView1.Invoke(new Action(() => { dataGridView1.DataSource = table; }));
    });
}

You can have similar Task.Run code blocks in button1_Click event handler to fill other DataGridView controls as well.

You can use either of these options:

  • Task.Run(()=>{ /* something */ });
  • new Thread(new ThreadStart(() => { /* something */ })).Start();
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Thank you for your response, I updated my invoke methods.But I want to fill gridviews at the same time. If I write the updating codes in button1_click method, the fillings run sequantial. I want to make parallel changes in windows form application. – snur Oct 19 '17 at 05:43
  • Put those 2 `Task.Run` in the same `button1_Click` event handler. And be informed that UI Thread is a single thread and at any time you can have a single Task in UI thread. But the sample code which is shared with you makes your UI thread responsive and lets just UI related code run at UI thread. – Reza Aghaei Oct 19 '17 at 05:47
  • I'm not sure about the number of cores, but sure about the number of threads which is only one thread. – Reza Aghaei Oct 19 '17 at 07:59
  • Thanks again.It's better right now the program has better performance then the first one. When I write like this: 'dataGridView1.Invoke(new Action(() => { dataGridView1.DataSource = table; dataGridView1.Refresh();}));' Data grid views refreshing one by one . As I understand , because of the main ui thread is a single thread. – snur Oct 19 '17 at 08:03
  • I am trying to use all of avaliable cores in order to have better perfomance. Does it task use only one core? When I watch to performance monitor throughputs are not maximum. I would like to run my code on all of avaliable cores to have maximum performance. I can make it with threadpools in console application but cant make it in form app. – snur Oct 19 '17 at 08:04
  • I'm not sure if it may make any difference, but if you are interested to use `Thread` class rather the `Task` class, read the update in answer. You can use `new Thread(new ThreadStart(() => { /* something */ })).Start();` instead of `Task.Run(()=>{ /* something */ });`. But you should know, also the `Task.Run()` is running in a different thread than UI thread. – Reza Aghaei Oct 19 '17 at 08:12