Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在.NET中实现数据绑定的线程安全收集_.net_Multithreading_Collections_Data Binding - Fatal编程技术网

在.NET中实现数据绑定的线程安全收集

在.NET中实现数据绑定的线程安全收集,.net,multithreading,collections,data-binding,.net,Multithreading,Collections,Data Binding,我有一个Windows窗体应用程序,它显示一个窗体,其中DataGridView绑定到继承BindingList的自定义集合。我正在使用BindingSource/DataSource机制进行数据绑定。表单是一个监视器,显示集合中包含的状态信息。集合的每个元素表示多个子线程之一的状态信息 我使用SynchronizationContext方法来确保集合中的ListChanged事件与UI线程同步,并且不会发生跨线程问题。但是,多个线程似乎仍然可以同时处理集合。这会导致数据绑定出现问题。以下是发生

我有一个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事件处理程序返回


有什么想法吗?

将视图绑定到集合的副本,然后适当地控制对集合的访问:确保线程在锁节中进行更新,并确保复制也使用同一对象上的锁完成

这还可以让您对写入请求进行排队,这样写入程序就不会阻塞,他们只需发送一条带有更新的消息,这可能对性能有好处


这只是一个想法。

将视图绑定到集合的副本,然后适当地控制对集合的访问:确保线程在锁节中进行更新,并确保复制也使用同一对象上的锁完成

这还可以让您对写入请求进行排队,这样写入程序就不会阻塞,他们只需发送一条带有更新的消息,这可能对性能有好处

只是个主意。

试试ConcurrentBag

试试ConcurrentBag