Асинхронная, поточно-ориентированная коллекция, реализующая INotifyCollectionChanged - PullRequest
1 голос
/ 14 марта 2012

Я использую Silverlight 5.0 и мне нужно реализовать IList<T> и IList. Моя коллекция будет использоваться для постоянного добавления и удаления элементов из ее внутренней коллекции, и пользовательский интерфейс будет иметь элементы, связанные с коллекцией. Из соображений производительности я не хочу, чтобы пользовательский интерфейс отображал каждый раз изменения коллекции, поскольку я хочу, чтобы в группу была внесена «группа» изменений, а затем было вызвано событие изменения коллекции. Я также хочу иметь возможность сделать это, используя подход Task.Factory, чтобы сохранить все асинхронным. Кто-нибудь видел хорошие примеры того, как этого добиться?

Ответы [ 2 ]

0 голосов
/ 01 января 2013

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

Используя этот подход, можно избежать чрезмерного числа ожидающих операций, поставленных в очередь через BeginUpdate. Там могут быть некоторые избыточные обновления, но, как правило, не слишком много. В некоторых случаях может быть полезно, чтобы код элемента управления ограничивал количество обновлений, которые он будет выполнять в секунду; если процедура обновления будет повторяться слишком много раз, запустите таймер и отключите обновления, пока не истечет таймер. Если время таймера истекло и обновления необходимы, выполните обновления и перезапустите таймер; если срок его действия истек и обновления не требуются, убейте таймер.

Попытка отразить каждое изменение в коллекции в событиях «обновления» может привести к обратным результатам. Просто убедитесь, что последнее обновление дисплея происходит полностью после последнего изменения в коллекции.

0 голосов
/ 31 декабря 2012

Многопоточная, наблюдаемая коллекция проблематична по своему дизайну. Например, если вы изменяете коллекцию, и это вызывает событие, в то время как это событие обрабатывается, коллекция может быть изменена в другом потоке. В результате обработчик, которому только что сообщили, что элемент был добавлен, может уже устареть (элемент может быть уже удален).

В качестве альтернативы, вы рассматривали возможность использования неизменяемой коллекции с событием, когда коллекция изменяется? Он по своей сути поточно-ориентирован и не будет страдать от вышеуказанной проблемы проектирования, если вы примените его правильно. Это может не соответствовать вашим требованиям для этого приложения - это трудно понять из вопроса.

...