1

I'm trying to update a listbox from another thread, what is the simplest way to achieve this?

I tried Invoking the textbox, but it didn't work.

private void dowork()
{
    TcpClient client = new TcpClient();
    client.Connect("192.168.1.3", 10);
    StreamWriter writer = new StreamWriter(client.GetStream());
    StreamReader reader = new StreamReader(client.GetStream());

    JObject o = new JObject();
    o.Add("comando", 1);
    o.Add("dir", @"C:\Users\klein\Desktop\Acionamentos");
    writer.Write(o.ToString());
    writer.Flush();
    JArray array = JArray.Parse(reader.ReadToEnd());
    for (int i = 0; i < array.Count; i++)
    {
        listBox1.Items.Add(array[i]);  //update GUI from this thread
    }
}

private void button1_Click(object sender, EventArgs e)
{
    Thread t = new Thread(dowork);
    t.Start();
}
2

3 Answers 3

1

I would use a BackgroundWorker, you can do your async stuff in DoWork, report your progress using bgworker.ReportProgress() and you will get the callback in ProgressChanged (I would call ReportProgress for every element processed), then you will be able to update your GUI controls.

The worker can also fire RunWorkerCompleted when it ends.

YourType arrayitem;

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    TcpClient client = new TcpClient();
    client.Connect("192.168.1.3", 10);
    StreamWriter writer = new StreamWriter(client.GetStream());
    StreamReader reader = new StreamReader(client.GetStream());

    JObject o = new JObject();
    o.Add("comando", 1);
    o.Add("dir", @"C:\Users\klein\Desktop\Acionamentos");
    writer.Write(o.ToString());
    writer.Flush();
    JArray array = JArray.Parse(reader.ReadToEnd());

    int percentage;

    for (int i = 0; i < array.Count; i++)
    {
        arrayitem = array[i];
        percentage = ((i + 1)*100)/array.Count;
        backgroundWorker1.ReportProgress(percentage);
    }
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    listBox1.Items.Add(arrayitem);
    progressBar1.Value = e.ProgressPercentage; // in case you'd want to add a progressbar
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    label1.Text = "Done";
}

Keep in mind your backgroundworker must have true in the WorkerReportProgress property.

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

2 Comments

Do you have any examples on this approach?
I added one example, hope it helps.
1

You can use Control.Invoke to get on UI thread and then update the list box.

However, I suggest you look at using a BackgroundWorker.

Comments

1

You need to use Dispatcher.BeginInvoke. You can check this link to have better understanding on how to update the UI controls from different thread. For example, if the listbox is named listbox1

for (int i = 0; i < array.Count; i++)
{
    listBox1.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
        new Action(delegate() { listBox1.Items.Add(array[i]) });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.