Mattigins
Mattigins

Reputation: 1016

How can i pass parameters to a background worker?

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.

Upvotes: 3

Views: 8272

Answers (2)

Mr_Engineer
Mr_Engineer

Reputation: 266

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

Upvotes: 1

Keith
Keith

Reputation: 1321

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."

Upvotes: 4

Related Questions