具有 BindingList 和 DataGridView 的多线程 C# 应用程序

本文关键字:多线程 应用程序 DataGridView BindingList 具有 | 更新日期: 2023-09-27 18:31:11

我为我的应用程序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字段)可以在那里手动编辑。

我的问题是,当计时器线程想要更新绑定列表内容时,我得到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如何处理列表。如何使此应用程序线程安全?

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

GUI 本身需要从 GUI 线程(主线程)更新。 .NET 提供了 BackgroundWorker 类来实现此目的。与GUI的通信可以通过ProgressChanged和RunWorkerComplete事件完成,您可以在其中传递选择的对象(例如要显示的对象)。

您无法

从其他线程更新 UI 线程。

您可以使用这篇文章来帮助您解决它:例如做

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