2009-05-27 1 views
0

У меня есть приложение Windows Forms, которое отображает форму с DataGridView, привязанную к пользовательской коллекции, которая наследует BindingList. Я использую механизм BindingSource/DataSource для привязки данных. Форма представляет собой монитор, который отображает информацию о состоянии, содержащуюся в коллекции. Каждый элемент коллекции представляет информацию о статусе для одного из многих дочерних потоков.Внедрить потокобезопасную сборку для привязки данных в .NET

Я использую метод SynchronizationContext, чтобы убедиться, что событие ListChanged из моей коллекции синхронизировано с потоком пользовательского интерфейса, и не возникает проблем с перекрестными потоками. Тем не менее, похоже, что несколько потоков одновременно могут работать с коллекцией. Это вызывает проблемы с привязкой данных. Ниже приведен пример исключения того, что произошел:

> 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 событие было поднята и обрабатывается в потоке пользовательского интерфейса.

Итак, мой вопрос заключается в том, как сделать мою коллекцию не только потокобезопасной, но и блокирующей, чтобы пользовательский интерфейс мог обновляться после события ListChanged до того, как разрешено другое изменение? Недостаточно очереди событий ListChanged, мне нужно заблокировать операцию, которая привела к запуску события ListChanged. Например, если я изменил свойство элемента, то поднял событие ListChanged (ListChangedType = ItemChanged), другой поток, который пытается добавить элемент в коллекцию, блокируется до тех пор, пока не вернутся обработчик (ы) события ListChanged.

Любые идеи?

ответ

Смежные вопросы