在.NET中实现数据绑定的线程安全收集
我有一个Windows窗体应用程序,它显示一个窗体,其中DataGridView绑定到继承BindingList的自定义集合。我正在使用BindingSource/DataSource机制进行数据绑定。表单是一个监视器,显示集合中包含的状态信息。集合的每个元素表示多个子线程之一的状态信息 我使用SynchronizationContext方法来确保集合中的ListChanged事件与UI线程同步,并且不会发生跨线程问题。但是,多个线程似乎仍然可以同时处理集合。这会导致数据绑定出现问题。以下是发生的异常的示例: System.ArgumentOutOfRange异常: 指定的参数超出范围 有效值的范围。参数名称: 行索引在 System.Windows.Forms.DataGridView.GetCellDisplayRectangleInt32 columnIndex,Int32行索引,布尔值 切割溢出 System.Windows.Forms.DataGridView.GetCellAdjustedDisplayRectangleInt32 columnIndex,Int32行索引,布尔值 切割溢出 System.Windows.Forms.DataGridView.InvalidateCellPrivateInt32 columnIndex,Int32行索引位于 System.Windows.Forms.DataGridView.OnCellCommonChangeInt32 columnIndex,Int32行索引位于 System.Windows.Forms.DataGridView.DataGridViewDataConnection.ProcessListChangedListChangedEventArgs 注视 System.Windows.Forms.DataGridView.DataGridViewDataConnection.currencyManager\u ListChangedObject 发送方,ListChangedEventArgs e位于 System.Windows.Forms.CurrencyManager.OnListChangedListChangedEventArgs 注视 System.Windows.Forms.CurrencyManager.List\u ListChangedObject 发送方,ListChangedEventArgs e位于 System.Windows.Forms.BindingSource.OnListChangedListChangedEventArgs 注视 System.Windows.Forms.BindingSource.InnerList\u ListChangedObject 发送方,ListChangedEventArgs e 这使我相信,在引发初始ListChanged事件并由UI线程处理之后,集合再次发生了更改 所以,我的问题是,如何使我的集合不仅是线程安全的,而且是阻塞的,这样UI就可以在ListChanged事件之后刷新,然后再进行另一次更改?仅对ListChanged事件排队是不够的,我需要阻止导致触发ListChanged事件的操作。例如,如果我更改元素的属性,然后引发ListChanged事件ListChangedType=ItemChanged,则尝试向集合添加项的另一个线程将被阻止,直到ListChanged事件处理程序返回在.NET中实现数据绑定的线程安全收集,.net,multithreading,collections,data-binding,.net,Multithreading,Collections,Data Binding,我有一个Windows窗体应用程序,它显示一个窗体,其中DataGridView绑定到继承BindingList的自定义集合。我正在使用BindingSource/DataSource机制进行数据绑定。表单是一个监视器,显示集合中包含的状态信息。集合的每个元素表示多个子线程之一的状态信息 我使用SynchronizationContext方法来确保集合中的ListChanged事件与UI线程同步,并且不会发生跨线程问题。但是,多个线程似乎仍然可以同时处理集合。这会导致数据绑定出现问题。以下是发生
有什么想法吗?将视图绑定到集合的副本,然后适当地控制对集合的访问:确保线程在锁节中进行更新,并确保复制也使用同一对象上的锁完成 这还可以让您对写入请求进行排队,这样写入程序就不会阻塞,他们只需发送一条带有更新的消息,这可能对性能有好处
这只是一个想法。将视图绑定到集合的副本,然后适当地控制对集合的访问:确保线程在锁节中进行更新,并确保复制也使用同一对象上的锁完成 这还可以让您对写入请求进行排队,这样写入程序就不会阻塞,他们只需发送一条带有更新的消息,这可能对性能有好处 只是个主意。试试ConcurrentBag试试ConcurrentBag