Microsoft-ui-xaml: Предложение: свойство автоматической отправки измененных событий в поток пользовательского интерфейса

Созданный на 17 мая 2019  ·  3Комментарии  ·  Источник: microsoft/microsoft-ui-xaml

Резюме

Разрешить привязки пользовательского интерфейса из свойств, которые вызывают изменения уведомлений из любого потока, отличного от пользовательского интерфейса.

Обоснование

Когда вы привязываете свойства, вы всегда должны вызывать уведомление об изменении свойства в потоке пользовательского интерфейса, иначе вы получите исключение во время выполнения. Это приводит к тому, что пользовательский интерфейс просачивается в ваши модели представлений и модели, так что вы можете подняться в нужном потоке, что, в свою очередь, не позволяет вам использовать INPC из стандартной библиотеки .NET (если вы не хотите попасть в bait'n'switch) .

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

Все это значительно усложняет код и повышает вероятность ошибок.

Это также вызывает проблему в WinUI 3.0, потому что теперь у нас есть два потока пользовательского интерфейса: устаревший поток UWP и поток WinUI: какой из них я должен поднять?

Сфера

  • Должна быть возможность вызывать INotifyPropertyChanged и INotifyCollectionChanged в любом потоке.
  • Должна быть возможность делать это дешево несколько раз за кадр, но запускать только одно обновление (последнее в победах)
  • Должна быть возможность обрабатывать устанавливаемое свойство во время его чтения для обновления пользовательского интерфейса.
  • Избегает переключения на поток пользовательского интерфейса, если он уже в нем.

Важные заметки

Проблемы с потоками, конечно, действительны, но я не верю, что это действительно проблема, в конце концов. Не имеет значения, что перед обновлением пользовательского интерфейса срабатывает несколько событий INPC, поскольку значение имеет только последнее из них. Это ничем не отличается от существующего кода, многократно переключающегося на поток пользовательского интерфейса. Как только первый из них переключится на поток пользовательского интерфейса, свойство уже может быть обновлено много раз, и, таким образом, последнее в выигрыше.
Естественно, при чтении значения должна быть короткая блокировка, которая предотвращает установку грязного флага, поэтому второй раунд обновлений пользовательского интерфейса происходит в следующем кадре, если свойство обновляется в то же время, когда оно считывается.
На самом деле, если значение, например, изменяется с false на true и обратно на false, свойство Dependency уже достаточно умно, чтобы определить, что значение не изменилось, и может оптимизироваться, не вызывая новый проход рендеринга из-за свойства без изменений.

feature proposal team-Markup

Самый полезный комментарий

Это очень серьезное беспокойство, спасибо, что подняли его. Поддержка сходства потоков для DP в структуре может не быть большой проблемой, но вполне может быть для разработчиков INPC.

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

Также есть самая большая проблема INPC, заключающаяся в отсутствии «текущего» значения при возникновении события. Могут быть ситуации, когда свойства не синхронизированы должным образом (например, SelectedIndex и ItemsSource не обновляются синхронно, а SelectedIndex теряет свое значение) или с пинг-понгом изменений, вызванных состояния свойств (например, изменения TextBox и фильтры регулярных выражений).

Это приводит к проблемам с INCC, когда вся коллекция должна быть должным образом защищена. Например, вы можете вызвать событие, ссылающееся на элемент, который был перемещен или которого больше нет.

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

Все 3 Комментарий

Это очень серьезное беспокойство, спасибо, что подняли его. Поддержка сходства потоков для DP в структуре может не быть большой проблемой, но вполне может быть для разработчиков INPC.

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

Также есть самая большая проблема INPC, заключающаяся в отсутствии «текущего» значения при возникновении события. Могут быть ситуации, когда свойства не синхронизированы должным образом (например, SelectedIndex и ItemsSource не обновляются синхронно, а SelectedIndex теряет свое значение) или с пинг-понгом изменений, вызванных состояния свойств (например, изменения TextBox и фильтры регулярных выражений).

Это приводит к проблемам с INCC, когда вся коллекция должна быть должным образом защищена. Например, вы можете вызвать событие, ссылающееся на элемент, который был перемещен или которого больше нет.

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

WPF понял это, так что, возможно, просто вытащите решение оттуда?

Отличное предложение. Мы делаем это для событий CollectionChanged (несколько случайно...), мы должны быть в состоянии сделать то же самое для NotifyPropertyChanged.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги