从静态方法访问成员变量

本文关键字:变量 成员 访问 静态方法 | 更新日期: 2023-09-27 18:01:37

我正在c# . net中编写一个WinForms应用程序,并希望从工作线程更新listview。我已经阅读了这里关于这方面的每一篇文章,但并没有真正完全理解Invoke和delegate的用法。事实上,这里的一些例子甚至无法编译,因为它抱怨从静态函数调用非静态控件。

我有一个ListViewItem,我只是想通过addlisttitem(…)传递给UI线程。最好的方法是什么?

目前我有

this.lvcontrol.Invoke(new Action(() => lvcontrol.Items.Add(item)));

这来自MyForm::AddListView(),它是一个静态函数。当然,编译器会抱怨你不能从静态方法中调用"this"或"lvcontrol"。如果方法不是静态的,我就不能从静态工作线程中调用该方法,静态工作线程是Form的成员函数。

从静态方法访问成员变量

您需要一个对lvcontrol的引用,以便代码知道您要更新的是哪个(您可以打开表单的两个副本!)。

如果lvcontrol是一个变量,那么把this放在开头eg

lvcontrol.Invoke(new Action(() => lvcontrol.Items.Add(item))

如果它不是你的代码要么都必须是非静态的,或者你将需要传递一个引用到表单周围(并使用该引用而不是this,例如如果from是对表单的引用

frm.lvcontrol.Invoke(new Action(() => frm.lvcontrol.Items.Add(item))

在多线程环境中使用静态数据可能存在许多问题。例如,如果一个线程正在迭代项的集合(为了显示视图),而另一个线程正在修改集合,您将得到一个异常。

您可能需要检查您的代码,并从同时使用读取和更新的多线程区域删除静态关键字,并添加一些数据并发处理。

我会推荐一些并发集合,您可以将其DataBind到ListView控件。在整个应用程序中传递对表单的引用并不是一个好主意。

我的建议是使用ConcurrentBag<T>ObservableCollection<T>

从UI线程给工作线程一个回调,工作线程可以使用它来传递ListView的数据,并让回调执行实际的ListView更新。