-1

テキスト ファイルを処理してコントロールを更新する Windows フォーム アプリケーションでリストビューを更新しようとしています。私の問題はクロススレッドに関連しています。コントロールを更新しようとするたびにエラーが発生します。アプリケーションをマルチスレッド化する前はエラーは発生していませんでしたが、UI はテキスト ファイル全体が処理されるまで更新されませんでした。各行が読み取られた後に UI を更新したいと思います。

関連するコードを投稿しました。私は今壁にいるので、誰かが私にいくつかのヒントを教えてくれることを願っています. エラーは、UpdateListView メソッドの if ステートメントで発生します。PingServer メソッドは私が書いたものであり、私の質問とは無関係であることに注意してください。

    private void rfshBtn_Click(object sender, EventArgs e)
    {
        string line;
        // Read the file and display it line by line.
        var file = new StreamReader("C:\\Users\\nnicolini\\Documents\\Crestron\\Virtual Machine Servers\\servers.txt");
        while ((line = file.ReadLine()) != null)
        {
            Tuple<string, string> response = PingServer(line);
            Thread updateThread = new Thread(() => { UpdateListView(line, response.Item1, response.Item2); });
            updateThread.Start();
            while (!updateThread.IsAlive) ;
            Thread.Sleep(1);
        }
        file.Close();
    }

    private void UpdateListView(string host, string tries, string stat)
    {
        if (!listView1.Items.ContainsKey(host)) //if server is not already in listview
        {
            var item = new ListViewItem(new[] { host, tries, stat });
            item.Name = host;
            listView1.Items.Add(item); //add it to the table
        }
        else //update the row
        {
            listView1.Items.Find(host, false).FirstOrDefault().SubItems[0].Text = host;
            listView1.Items.Find(host, false).FirstOrDefault().SubItems[1].Text = tries;
            listView1.Items.Find(host, false).FirstOrDefault().SubItems[2].Text = stat;
        }
    }
4

1 に答える 1

1

Winform コンポーネントは、メイン スレッドからのみ更新できます。他のスレッドから更新を行いたい場合は、 を使用してメイン スレッドで更新コードを呼び出す必要がありますcomponent.BeginInvoke()

それ以外の

 listView1.Items.Add(item);

次のように書くことができます:

listView1.BeginInvoke(() => listView1.Items.Add(item));

スレッドが UI の更新のみを行い、それ以外にリソースを集中的に使用しない場合は、それをまったく使用せず、メイン スレッドからメソッドとして UpdateListView を呼び出すのが合理的です。

于 2013-06-18T21:51:25.777 に答える