Click here to Skip to main content
15,885,546 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());
        }
    }
}
 
Share this answer
 
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