Click here to Skip to main content
14,865,273 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi, I'm developing a database software. I have many forms there and I also have a class and a method to retrieve data from database into ListView. So, I don't need to write methods anymore when I need to fill ListView with data. Here I'm using multi threads to avoid "Not Responding Program" when getting huge data. Unfortunately, this method has an error "cross-thread operation not valid accessed from a thread other than the thread it was created on"
C#
public class DatabaseListView
{
    bmtfunc.Databases d = new Databases();

    Int32 listViewRow = 0;
    Int32 listViewCol = 0;

    DataTable dataTable = new DataTable();

    //retrieving data to Listview
    public void RetrieveToListView(string SqlQuery, ListView Lv)
    {
        d.RetrieveToDataTable(SqlQuery, dataTable);

        ParameterizedThreadStart paramThread = delegate { this.ListViewRows(SqlQuery, Lv); };
        new Thread(paramThread).Start();

        //new Thread(new ParameterizedThreadStart(this.ListViewRows)).Start(SqlQuery);

    }

    private void ListViewRows(object SqlQuery, ListView listView)
    {
        if (dataTable.Rows.Count < 1)
            return;

        if (listView.InvokeRequired)
            listView.Invoke(new MethodInvoker(delegate { ListViewRows(SqlQuery, listView); }));

        for (listViewRow = 0; listViewRow < dataTable.Rows.Count -1; listViewRow++) //loop for rows
        {

            Thread.Sleep(50);
            ListViewItem listViewItem = listView.Items.Add(dataTable.Rows[listViewRow][0].ToString());
            for (listViewCol = 1; listViewCol < dataTable.Columns.Count; listViewCol++) //loop for columns
                listViewItem.SubItems.Add(dataTable.Rows[listViewRow][listViewCol].ToString());
        }

    }
}


Help me correct my code, please. Thanks in advance.
Posted

1 solution

You can only access GUI objects from the thread they were created on - if you try to access them from a different thread, you get the cross-thread error you are talking about. So you have correctly checked for invoke, and invoked if you need it.

Unfortunately, the same goes for creating controls - they can only be created on the UI thread.
So, try adding an else condition:
C#
private void ListViewRows(object SqlQuery, ListView listView)
{
    if (dataTable.Rows.Count < 1)
        return;

    if (listView.InvokeRequired)
        listView.Invoke(new MethodInvoker(delegate { ListViewRows(SqlQuery, listView); }));
    else
    {
        for (listViewRow = 0; listViewRow < dataTable.Rows.Count -1; listViewRow++) //loop for rows
        {
            Thread.Sleep(50);
            ListViewItem listViewItem = listView.Items.Add(dataTable.Rows[listViewRow][0].ToString());
            for (listViewCol = 1; listViewCol < dataTable.Columns.Count; listViewCol++) //loop for columns
                listViewItem.SubItems.Add(dataTable.Rows[listViewRow][listViewCol].ToString());
        }
    }
}
   
Comments
derodevil 6-May-12 15:01pm
   
Many many thanks OriginalGriff. It works as I want. I'll vote and accept your solution.
OriginalGriff 6-May-12 15:02pm
   
You're welcome!
Monjurul Habib 8-May-12 16:27pm
   
5!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900