简体   繁体   中英

Insert many row to DatagridView using Multiple threads C#?

I'm doing scrap program from website. I have many threads to update info to datagridview. I'm using dataset to set binding source to datagridview. When i inserted about 100k row. My GUI program show "not responding". I don't know how to solve it. This is my delegate to insert :

public void InsertLine(string line)
{
  this.MyDV.BeginInvoke(new MethodInvoker(delegate()
  {                 
    string[] park = Regex.Split(line, @",");
    try
    {
        //Insert new row
        MyDatasset.MyTableRow row = this.MyDataSet.MyTable.NewMyTableRow();
        row.Message = park[0].Trim();
        row.From = park[1].Trim();              
        this.MyDataSet.MyTable.Rows.Add(row);

        //Set color text for new row
        DataGridViewRow myrow = (from DataGridViewRow r in MyDV.Rows
                                 where (long)r.Cells[clId.Name].Value == row.Id
                                 select r).FirstOrDefault();
        if (myrow != null)
        {
            myrow.Cells[clFrom.Name].Style.ForeColor = Color.Blue;
            myrow.Cells[clMessage.Name].Style.ForeColor = Color.Blue;
        }       
    }
    catch { }
    try
    {
        this.MyDV.FirstDisplayedScrollingRowIndex = this.MyDV.Rows[this.MyDV.Rows.Count - 2].Index; //Scroll to lastest row
    }
    catch { }       
}));  }

Can you guys help me? I'm getting confused many hours with it. Thanks in advance.

What you are doing is invoking that code on the UI thread. It's a loop that iterates potentially many rows. This is probably taking a long time and blocking the UI thread from doing anything else. You could try breaking up the work into smaller (or fixed-size) chunks and individually invoking them--which would allow the UI thread to process other messages in between.

Alternatively, you could do the work in the Application.Idle event; but, you'd likely still have to break up the work into fixed-sized chunks because you should only take a small, ideally fixed, amount of time in the Idle event.

I think the problem that you have here is that you are not locking the code above and it is been accessed by multiple threads all at the same time.

You need to use :-

Lock (this)

{

this.MyDV.BeginInvoke(new MethodInvoker(delegate()
  {                 
    string[] park = Regex.Split(line, @",");
    try
    {
        //Insert new row
        MyDatasset.MyTableRow row = this.MyDataSet.MyTable.NewMyTableRow();
        row.Message = park[0].Trim();
        row.From = park[1].Trim();              
        this.MyDataSet.MyTable.Rows.Add(row);

        //Set color text for new row
        DataGridViewRow myrow = (from DataGridViewRow r in MyDV.Rows
                                 where (long)r.Cells[clId.Name].Value == row.Id
                                 select r).FirstOrDefault();
        if (myrow != null)
        {
            myrow.Cells[clFrom.Name].Style.ForeColor = Color.Blue;
            myrow.Cells[clMessage.Name].Style.ForeColor = Color.Blue;
        }       
    }
    catch { }
    try
    {
        this.MyDV.FirstDisplayedScrollingRowIndex = this.MyDV.Rows[this.MyDV.Rows.Count - 2].Index; //Scroll to lastest row
    }
    catch { }       
}));  }

}

This should make each thread wait in turn to use your insert delegate.

Also check out :- http://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.71).aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM