How to update Listview from Background Worker in WinForm-C#.Net ?

How to solve ‘Cross-thread operation not valid: error in C# Background Worker


C# WinForm provides Background Worker Control that is capable of run asynchronous job in background. This must be ideal for fetching data in the background .

What about updating UI from background ? Like update a listview items from database . Let’s begin from setup.

How to ?

The Background Worker control has a event ,DoWork where we can add our background tasks.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{
// logic here         
}

We can use the RunWorkerCompleted to apply logic which will executed after completion.

In the form load event (or from any event ) you can start the task by running

   this.backgroundWorker1.RunWorkerAsync();

Problem with UI and Worker

When you try to access a component in the UI from a Background Worker DoWork event, may end up like this.

System.InvalidOperationException: ‘Cross-thread operation not valid: Control ‘listView1’ accessed from a thread other than the thread it was created on…

Solution

To bypass this error C#.Net provides invoke method which execute the delegate specified.

To add items to the listview from a background worker I used the following code snippet which uses a MethodInvoker and a delegate

        try
            {
listView1.Invoke(new MethodInvoker(
                                 delegate
                                 {
                                     item = new ListViewItem("");
                                     item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "Some Column Value Here"));                                       
                                     listView1.Items.Add(item);
                                 }
                                 ));               
           }
            catch (Exception)
            {
                throw;
            }

I hope this will help you and recommend the following snippets.

Linq – suming rows,create list of custom fields,create model class object list from data table

Linq – suming rows,create list of custom fieds,create model class list from data table


Querying data from a data table in .Net is easy with Linq. Linq is a query language which is applicable to all type of objects such as List,Tables etc in .Net . Infact you can simply convert the table data to object like List of generic type or cutom Model class object with Linq operation, in limited sense you can forget loops.

Sum table column

Let’ learn how to simply sum up a column in your data table using Linq.

var comms = (from p in public_members.payroll_posting.AsEnumerable() where p.Field<string>
("eid") == "1001" select p.Field<decimal>("amount")).Sum();

The above linq simply fetch amount from the data table for employee id “1001”. I also place an outer pareanthesis for summing up. The parenthesis come handy when you want to convert the values you selected to Arrays,List or perform aggragate functions like Sum,Count etct

Create List of rows with custom list

LINQ – CREATE LIST OF OBJECTS FROM A DATA TABLE
 var comm_list = (from p in posting.AsEnumerable() where  p.Field<string>("type") == 
"Commission" select new { amount = p.Field<decimal>("amount"), eno = p.Field<int>("pp_no"),
 edate = p.Field<DateTime>("post_date") }).ToList();

I have a table in which I store all employee payments under seperate types. I just want to create a list of commission paid to the employees as new list with custom column which is not exist in the data table .

The select new will create a model class like fields.

Create a list of objects from Linq query

Create list of Objects[Model class] with Linq

Following LinQ will help to build Model class object list from a data table, remember I used myown Model class which I not provided here. Use your own

 var payrolls = (from pp in payroll_entries.AsEnumerable()
                                  join emp in employees.AsEnumerable() on pp.Field<string>("eid") equals emp.Field<string>("eid")
                                  select new
                                  {
                                      p = new PayRollEntryModel()
                                      {
                                          VNO = pp.Field<int>("pe_no").ToString(),
                                          DATE = pp.Field<DateTime>("pe_date"),
                                          Employee = LedgeName(emp.Field<int>("lid")),
                                          EID = Convert.ToInt32(pp.Field<string>("eid")),
                                          CashAccount = LedgeName(pp.Field<int>("crledger")),
                                          Total = string.Format("{0:0.00}", pp.Field<decimal>("amount")),
                                          CrACID = Convert.ToInt32( pp.Field<int>("cash_ac")),
                                          Narration = pp.Field<string>("narration"),
                                          DrAcid = Convert.ToInt32( emp.Field<int>("lid")),                                         
                                          Allownaces=pp.Field<string>("allowances"),
                                          Commission=pp.Field<string>("comm"),
                                          Advance=pp.Field<string>("advance"),
                                          Basic=pp.Field<string>("bp"),
                                          Deductions=pp.Field<string>("deductions"),
                                          WDs= pp.Field<decimal>("wdays").ToString() ,
                                          WHs=  pp.Field<decimal>("whours").ToString(),                                       


                                      }
                                  }.p).ToList<PayRollEntryModel>();

At the 26th line of the above code I used .p because the linq only create a list of p which is a anonimous type. I want is a list of the Model class object which is PayRollEntryModel.

I think this will help somebody out there… leave comment and share your thoughts

All the examples I demonstrated here is part of my personal project and I should say these are working very well.

Advertisements