我有public static class MyGlobals
用于我的应用程序范围的变量和多个线程处理和更改这些变量。
public static class MyGlobals
{
public static BindingList<Device> devicesList;
public static BindingList<Device> availableList;
public static object listLock = new object();
}
我有一个Timer
线程,用于更新列表的一部分(例如Device.status
字段)和UI线程,其中这些列表绑定到DataGridView
表和一些字段(例如Device.description
字段)可以在那里手动编辑。
我的问题是,当Timer线程想要更新Binding列表内容时,我得到InvalidOperationException
:
Additional information: Cross-thread operation not valid: Control 'gridView1' accessed from a thread other than the thread it was created on.
我在修改lock(listLock)
列表的每个代码块周围使用MyGlogals
语句,但我无法控制DataGridView
处理列表的方式。如何使这个应用程序线程安全?
答案 0 :(得分:2)
您无法从其他线程更新UI线程。
您可以使用this post来帮助您解决问题: 例如
foreach (Device device in MyGlobals.devicesList)
{
Invoke(new MethodInvoker(delegate {
device.text = "newText";
}));
}
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerAsync();
和bg_DoWork:
void bg_DoWork(object sender, DoWorkEventArgs e)
{
foreach (Device device in MyGlobals.devicesList)
{
device.text = "newText";
}
}
答案 1 :(得分:1)
GUI本身需要从GUI线程(主线程)更新。 .NET为此提供了BackgroundWorker类。具有GUI的通信可以通过/或ProgressChanged和RunWorkerCompleted事件完成,您可以在其中传递选择的对象(例如,要显示)。