1

別のスレッドからリストボックスを更新しようとしていますが、これを実現する最も簡単な方法は何ですか?

テキストボックスを呼び出してみましたが、うまくいきませんでした。

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();
}
4

3 に答える 3

1

を使用し、BackgroundWorkerで非同期処理を実行し、 をDoWork使用して進行状況を報告するbgworker.ReportProgress()と、 でコールバックが取得されますProgressChanged(処理されたすべての要素に対して ReportProgress を呼び出します)。その後、GUI コントロールを更新できます。

ワーカーはRunWorkerCompleted終了時に発砲することもできます。

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

WorkerReportProgressバックグラウンド ワーカーのプロパティは true でなければならないことに注意してください。

于 2013-01-26T23:13:03.553 に答える
1

を使用Control.Invokeして UI スレッドにアクセスし、リスト ボックスを更新できます。

ただし、を使用して見ることをお勧めしますBackgroundWorker

于 2013-01-26T23:04:30.260 に答える
1

Dispatcher.BeginInvoke を使用する必要があります。このリンクをチェックして、別のスレッドから UI コントロールを更新する方法をよりよく理解することができます。たとえば、リストボックスの名前が 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]) });
}
于 2013-01-28T06:26:52.753 に答える