Массовые обновления сложного интерфейса - PullRequest
5 голосов
/ 17 июля 2011

У меня очень сложный пользовательский интерфейс с постоянно меняющейся строкой состояния с несколькими типами сообщений о состоянии и пользовательским интерфейсом со сложным элементом управления диаграммой и загруженной ориентировочной географической картой.

Теперь контекст данных этих небольших, но сложныхрегионы имеют одинаково сложные ViewModels, такие как StatusBarVM, ChartingVM, GeoMapVM и т. д. Они реализуют INotifyPropertyChanged и ObservableCollections.

Подсчет моих обновлений Я вижу, что у меня есть около 5000 элементов пользовательского интерфейса (метки, индикаторы выполнения, точки данных диаграммы, bgcolorsbrushesи т. д.), которые меняются со скоростью 1000 обновлений элементов данных в секунду.

Каков наилучший способ выполнить это массовое обновление данных в пользовательском интерфейсе WPF?

Является ли модель привязки WPFспособен на такие огромные обновления?Если так, то как?Потому что я вижу, что это не оптимально в моем случае.Я также использую bgworker (для индикаторов прогресса) и использую DIspatcher BeginInvoke ... но дело в том, что даже тогда обновления действительно вешают поток пользовательского интерфейса, поскольку сообщения диспетчера попадают в очередь в ожидании завершения.

Я не могу реализовать виртуализацию, так как статусы отображаются в режиме реального времени, и я должен видеть их все в пользовательском интерфейсе передо мной ... Я не могу позволить себе пропустить их даже на пару секунд (например, по-разному меняющиеся географические данные спутника).

Пожалуйста, помогите мне определить правильный инструмент или какой-либо способ создания сложного, но очень отзывчивого пользовательского интерфейса WPF.Это Dispatcher.PushFrame ()?

1 Ответ

4 голосов
/ 17 июля 2011

При таком количестве обновлений в секунду вы будете получать сообщения об обновлениях «в резервной копии» в очереди, поэтому ваши фоновые обновления блокируются.

Чтобы решить эту проблему, вам нужно ограничитьколичество генерируемых событий обновления.

Я бы использовал такой подход:

В моих ViewModels замените обычную реализацию INotifyPropertyChanged вызовом одноэлементного объекта, который отправитуведомление от имени этого объекта.

private void OnPropertyChanged(string propertyName)
{
    PropertyChangedNotifier.Notify(this, propertyName, propertyChanged);
}

Где propertyChanged - переменная-член, хранящая обработчики событий этого объекта.

Метод Notify будет выглядеть примерно так:

public static void Notify(
    object sender, 
    string propertyName, 
    PropertyChangedEventHandler handlers)
{ ... }

В уведомителе не отправлять событие немедленно - просто сохранить факт, что его нужно отправить.

Если вы получаете уведомление несколько раз для одного и того же объекта / свойства, откажитесь от дополнительных уведомлений.Если вы получаете уведомление много раз для одного и того же объекта, но с разными свойствами, замените уведомление на одно для всех свойств .

Теперь используйте таймер потока UX, чтобы «освободить» уведомлениякаждые 50 мс или около того - все еще достаточно быстро, чтобы пользователь не заметил никакой разницы, и это выглядит как обновления в реальном времени, но достаточно медленно, чтобы обнаруживать (и удалять) дублирующиеся уведомления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...