具有BindingList <t>和DataGridView </t>的多线程C#应用程序

时间:2013-09-12 08:36:50

标签: c# multithreading winforms datagridview

我有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处理列表的方式。如何使这个应用程序线程安全?

2 个答案:

答案 0 :(得分:2)

您无法从其他线程更新UI线程。

您可以使用this post来帮助您解决问题: 例如

     foreach (Device device in MyGlobals.devicesList)
     {
        Invoke(new MethodInvoker(delegate {
             device.text = "newText";
        }));
     }

或使用background worker

     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的通信可以通过/或ProgressChangedRunWorkerCompleted事件完成,您可以在其中传递选择的对象(例如,要显示)。