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

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

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

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

  listView2.Invoke(new Action( () => listView2.Items.Clear() ) ); 

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

您需要使用Control.Invoke调用UI线程上的代码来更新listView。

这是我用于混乱UI控件的方法的模式

 public void DoSomethingToUI(string someParams) { if(UIControl.InvokeRequired) { UIControl.BeginInvoke(()=>DoSomethingToUI(someParams)); return; } //Do something to the UI Control }