3

I currently have a function that populates a listview with data. This function get passed parameters.

I now want to populate the listview in a different thread from the main ui thread. However i am a little unsure how i would pass the parameters to the thread.

3
  • 1
    You cannot populate a ListView in a different thread. Commented Dec 9, 2014 at 13:38
  • If i cannot populate the listview, then how would i go about turning my function into a background worker? Commented Dec 9, 2014 at 13:52
  • Gather the data you want to display in the list view in a worker thread. Binding or filling the list view needs to happen in the RunWorkerCompleted event handler. If that takes too long then your UI is drastically broken, displaying lists with thousands of items is a exceedingly user-hostile. Commented Dec 9, 2014 at 14:10

2 Answers 2

4

It has to be passed as a parameter (object) through RunWorkAsync. Be sure to cast it to whatever you passed in.

Private Sub frm_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load bgwThread.RunWorkerAsync('your parameters here') 'e.g.: Dim sTemp As String = "Hello" bgwThread.RunWorkerAsync(sTemp) End Sub Private Sub bgWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bgwThread.DoWork Dim sThisIsYourParameter As String = CStr(e.Argument) '... DoStuff() End Sub 

Although as Hans said above, you can't populate the ListView in another thread. This is just "how to pass a parameter to a backgroundworker."

Sign up to request clarification or add additional context in comments.

2 Comments

And that code will likely generate a cross threading error because you are doing UI work (MessageBox) on a thread other than the UI thread.
Oh, yea. Thank you. I was just putting that in for an example.
1

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"); } } } 

Program Output

1 Comment

Related tip: You cannot use 'await' inside a BackgroundWorker, as it causes the BGW to complete. You can only run synchronous code inside a BGW. I learned this the hard way. If you need async functions, use Task.Run. e.g. await Task.Run( async () => { await Task.Delay(100); });

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.