Подход, который я бы предложил, состоял бы в том, чтобы иметь различные флаги для различных аспектов коллекции, для которых может потребоваться обновление пользовательского интерфейса. Если что-то в коллекции изменяется и конкретный флаг не установлен, установите его и используйте Control.BeginInvoke
для предоставленного элемента управления и делегата (используйте либо Interlocked
, либо блокировки, чтобы убедиться, что флаг test-and-set выполнен в потоке безопасная мода). Метод обновления пользовательского интерфейса должен проверить и очистить соответствующие флаги перед выполнением своих обновлений; если были выполнены какие-либо обновления, метод должен выполнить цикл и повторно протестировать все флаги, пока не завершит работу, не выполняя никаких обновлений.
Используя этот подход, можно избежать чрезмерного числа ожидающих операций, поставленных в очередь через BeginUpdate
. Там могут быть некоторые избыточные обновления, но, как правило, не слишком много. В некоторых случаях может быть полезно, чтобы код элемента управления ограничивал количество обновлений, которые он будет выполнять в секунду; если процедура обновления будет повторяться слишком много раз, запустите таймер и отключите обновления, пока не истечет таймер. Если время таймера истекло и обновления необходимы, выполните обновления и перезапустите таймер; если срок его действия истек и обновления не требуются, убейте таймер.
Попытка отразить каждое изменение в коллекции в событиях «обновления» может привести к обратным результатам. Просто убедитесь, что последнее обновление дисплея происходит полностью после последнего изменения в коллекции.