Old post, but here is a complete solution for anyone stumbling on this post. This allows passing parameters to a Backgroundworker, supports cancellation, and passes back information to the main thread (via ProgressChanged) where it can update the ListView. I created a solution from scratch. Tested working.
C# / .NET Framework 4.6.2 / VS2019 build 16.4.1
BackgroundWorker1 properties:
WorkerReportsProgress = True
WorkerSupportsCancellation = True
using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; namespace test2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(Object sender, EventArgs e) { listView1.View = View.Details; listView1.GridLines = true; listView1.Columns.Add("Store",100); listView1.Columns.Add("Product", 100); listView1.Columns.Add("Price", 60); listView1.Columns.Add("Qty", 60); } private void backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) { if(!(e.Argument is String store)) return; List<String> items = new List<String>(); if(backgroundWorker1.CancellationPending) {e.Cancel = true; return;} items.Add(store); items.Add("Bananas"); items.Add("0.79"); items.Add("50"); backgroundWorker1.ReportProgress(0, items); } private void backgroundWorker1_ProgressChanged(Object sender, ProgressChangedEventArgs e) { if(!(e.UserState is List<String> resultitems)) return; ListViewItem itm = new ListViewItem(resultitems.ToArray()); listView1.Items.Add(itm); } private void backgroundWorker1_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e) { //Do any final cleanup once backgroundworker is complete } private void button1_Click(Object sender, EventArgs e) { if(backgroundWorker1.IsBusy) { backgroundWorker1.CancelAsync(); return; } backgroundWorker1.RunWorkerAsync("Glendale"); } private void button2_Click(Object sender, EventArgs e) { if(backgroundWorker1.IsBusy) { backgroundWorker1.CancelAsync(); return; } backgroundWorker1.RunWorkerAsync("Toledo"); } } }
