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

时间:2009-05-27 18:53:25

标签: .net multithreading collections data-binding

我有一个Windows窗体应用程序,它显示一个表单,其中DataGridView绑定到继承BindingList的自定义集合。我正在使用BindingSource / DataSource机制进行数据绑定。表单是一个监视器,显示集合中包含的状态信息。集合中的每个元素表示许多子线程之一的状态信息。

我正在使用SynchronizationContext方法来确保我的集合中的ListChanged事件与UI线程同步,并且不会发生跨线程问题。但是,似乎多个线程仍然可以同时使用该集合。这会导致数据绑定问题。以下是已发生的异常的示例:

> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: rowIndex
>    at System.Windows.Forms.DataGridView.GetCellDisplayRectangle(Int32 columnIndex, Int32 rowIndex, Boolean cutOverflow)
>    at System.Windows.Forms.DataGridView.GetCellAdjustedDisplayRectangle(Int32 columnIndex, Int32 rowIndex, Boolean cutOverflow)
>    at System.Windows.Forms.DataGridView.InvalidateCellPrivate(Int32 columnIndex, Int32 rowIndex)
>    at System.Windows.Forms.DataGridView.OnCellCommonChange(Int32 columnIndex, Int32 rowIndex)
>    at System.Windows.Forms.DataGridView.DataGridViewDataConnection.ProcessListChanged(ListChangedEventArgs e)
>    at System.Windows.Forms.DataGridView.DataGridViewDataConnection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)
>    at System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
>    at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
>    at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
>    at System.Windows.Forms.BindingSource.InnerList_ListChanged(Object sender, ListChangedEventArgs e)

这让我相信在最初的ListChanged事件被引发并由UI线程处理后,该集合再次被更改。

所以,我的问题是如何使我的集合不仅是线程安全的而且是阻塞的,以便在允许另一个更改之前,在ListChanged事件之后UI可以刷新?排队ListChanged事件是不够的,我需要阻止导致ListChanged事件被触发的操作。例如,如果我更改了元素的属性然后引发了ListChanged事件(ListChangedType = ItemChanged),则阻止尝试将项添加到集合的另一个线程,直到ListChanged事件处理程序返回。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您可以使用自己实现的任何接口来包装它。看看this answer to the same question ...