C#Thread问题

3 c#

我发生的是从上一次按钮点击动态创建的列表视图.然后ti启动一个后台工作程序,其中应该清除listview并每30秒用新信息填充iistview.
我不断得到:跨线程操作无效:控制'listView2'从一个线程访问,而不是创建它的线程.

  private void watcherprocess1Updatelist()
    {
        listView2.Items.Clear();
        string betaFilePath1 = @"C:\Alpha\watch1\watch1config.txt";
        using (FileStream fs = new FileStream(betaFilePath1, FileMode.Open))
        using (StreamReader rdr = new StreamReader((fs)))
        {
            while (!rdr.EndOfStream)
            {
                string[] betaFileLine = rdr.ReadLine().Split(',');
                using (WebClient webClient = new WebClient())
                {
                    string urlstatelevel = betaFileLine[0];
                    string html = webClient.DownloadString(urlstatelevel);
                    File.AppendAllText(@"C:\Alpha\watch1\specificconfig.txt", html);
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 6

您无法从后台线程访问ListView.您需要在UI线程上执行此操作.

有两个选项 - 首先,您可以切换它以使用Windows.Forms.Timer每30秒触发一次.这将发生在UI线程上,这将完全避免此问题,但将处理移动到UI线程.如果您的处理速度很慢,这可能会导致"挂起".

或者,使用Control.Invoke将对ListView的调用封送回UI线程:

 listView2.Invoke(new Action( () => listView2.Items.Clear() ) );
Run Code Online (Sandbox Code Playgroud)

无论如何,我会重新考虑使用BackgroundWorker.它不适用于定期发生的"定时事件".您应该考虑更改为Windows.Forms.Timer(UI线程),如果没有长时间处理,或者a System.Timers.Timer(在后台线程上运行),如果处理将需要一段时间.这是一个比永远不会终止的BackgroundWorker更好的设计选项.