views:

4938

answers:

7

Hi

I want my backgroundworker to add items to a list box, it appears to do so when debugging but the listbox doesn't show the values. I suspect this is something to do with adding items whilst inside the backgroundworker thread, do I need to add these to an array and then populate the list box from the array during backgroundWorker1_RunWorkerCompleted?

Thanks for the help.

+1  A: 

You can add them while on a background thread via:

Form.Invoke

or

Form.BeginInvoke

which are required to marshall the call from a background thread to a main UI thread. However i'm pretty sure BackgroundWorker offers an event that automatically gets called on the Foreground thread and you should be able to update on this event without any problems. This is "ProgressChanged" which can be fired by the background worker process by calling ReportProgress.

Have you tried calling .Refresh() on the listbox as well?

Quibblesome
+4  A: 

You can, but you must advise your Backgroundworker to report state, and send the input for the box with the current state to that event. In the method for that event, you can access the box and put the new value in.

Otherwise you need to invoke manually.

 public Form1()
        {
            InitializeComponent();

            BackgroundWorker bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerAsync();
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                ((BackgroundWorker)sender).ReportProgress(0, i.ToString());
            }
        }

        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            listBox1.Items.Add((string)e.UserState);
        }
BeowulfOF
A drawback of this method (adding items one by one) would be that one cannot enclose listbox population within BeginUpdate/EndUpdate.
Sorin Comanescu
A: 

See Why am I getting this error:”Cross-thread operation not valid: Control lbFolders accessed from a thread other than the thread it was created on.”? for more info.

paul
This is not very usefull, as one must first read through the whole thread.
BeowulfOF
Is that really a problem for you! This is just a helpful link to a similar discussion. All answers are useful for gaining a better understanding and the thread it not *that* long.
paul
+4  A: 

You can use Invoke like this:

private void AddToListBox(object oo)
{
    Invoke(new MethodInvoker(
                   delegate { listBox.Items.Add(oo); }
                   ));
}
Gonzalo Quero
Yes, but the BackgroundWorker does this automatically with the event.
BeowulfOF
I know, I'm only providing an alternative ;)
Gonzalo Quero
Alternatives are always good, the feeling of having a choice is essential for the matrix ;-)
BeowulfOF
A: 

I add functions like the following so that I can add items to the list box from either the main thread or background threads. Thi thread checks if a Invoke is necessary and then uses Invoke if it is necessary.

  delegate void AddListItemDelegate(string name,object otherInfoNeeded);

  private void
     AddListItem(
        string name,
        object otherInfoNeeded
     )
  {
     if (InvokeRequired)
     {
        BeginInvoke(new AddListItemDelegate(AddListItem), name, otherInfoNeeded
        return;
     }

     ... add code to create list box item and insert in list here ...
  }
Marcus Erickson
A: 

Hi,

I am using backgroundworker thread. I can't see the added items in listbox even if method invoked. When It InvokeRequired == true it updates and shows the item in listBox, but when it is false it adds item in listbox but not show addedItem.

excerpt of Code is

if (InvokeRequired)
{
     Listbox.Invoke(fn);
}
else
{
    ListBox.Items.Add(value);  //? It adds value but not show 
    this.refresh();
}


fn()
{
   ListBox.Items.Add(value); // here it adds value and show
}
Dilip
Better post this as a new question ("Ask Question" button in the top right of the page). More people will see it that way.
sth
A: 

Application.Doevents() function will solve the problem

Abdul Hameed