Коллега столкнулся с проблемой в своей XAML-программе. Они использовали элемент управления FlipView, привязанный к коллекции, но при попытке навигации по FlipView с помощью вспомогательного программного обеспечения (assistive technology) в некоторых случаях навигация не выполнялась.
Через некоторое время они вернулись с решением загадки.
Команда заметила, что их модель данных состоит только из строк и других типов-значений, поэтому они решили объявить модель данных как struct вместо полноценного runtimeclass, чтобы избежать большого количества шаблонного кода. Но если вы определяете её как struct, то большая часть этого кода оказывается ненужной.
Дело в том, что то, что делает типы-значения типами-значениями — это копирование по значению, а не по ссылке. Это означает, что когда XAML вызывает GetAt(n) на m_pages, чтобы получить n-й элемент, он получает копию MyPageContent и связывается с этой копией.
Именно в этом и была проблема.
Когда код хочет перейти к определённому элементу по запросу вспомогательного средства, он передаёт MyPageContent, к которому нужно перейти, но это опять же просто ещё одна копия, потому что типы-значения всегда передаются копированием. XAML отвечает: «У меня нет этого парня» и отменяет навигацию. (XAML не понимает, что у него есть объект, очень похожий на тот объект. Но это не имеет значения, потому что это не тот же самый объект.)
Хитрый упрощённый приём оказался источником проблемы.
Теперь, хотя верно, что для реализации runtime class в C++/WinRT требуется много набивания кода, существуют помощники, уменьшающие объём необходимого кода. В Windows Implementation Library (wil) заголовочный файл cppwinrt_authoring.h содержит классы, упрощающие реализацию событий и свойств. Он использует CRTP так же, как обсуждалось ранее.
Мы можем обойтись использованием single_threaded_property, потому что свойства записываются только при конструировании, поэтому одновременные чтения не приведут к проблемам.
Рэймонд участвует в эволюции Windows более 30 лет. В 2003 году он завёл веб‑сайт, известный как The Old New Thing, который стал значительно более популярным, чем он мог себе представить, развитие чего до сих пор вызывает у него легкое беспокойство. Сайт породил книгу с тем же названием The Old New Thing (Addison Wesley, 2007). Иногда он появляется в аккаунте Windows Dev Docs в Twitter, чтобы рассказывать истории, не несущие полезной технической информации.
Обсуждение закрыто. Войдите в систему, чтобы редактировать или удалять существующие комментарии.
В статье по адресу https://devblogs.microsoft.com/oldnewthing/20160826-00/?p=94185 ссылка «Sound familiar?» сломана (должна вести на «https://devblogs.»).
// [вы можете] удалить этот комментарий после исправления.
Видеть «single_threaded_property» и комментарий «concurrent reads are not going to cause problems» вызывает странное когнитивное торможение. Нужно время, чтобы понять, что аспект single-threaded, вероятно, не проверяется во время выполнения. Очевидно задним числом, но на первый взгляд это похоже на странность.
Да. Я даже на мгновение подумал, что это означает сериализованный доступ через блокировки, а не отсутствие блокировок, потому что их не должно быть нужно, поскольку свойство не должно менять своё состояние при чтении.
В последнем примере кода, разве m_title не должен быть заменён на Title и т. п.?
Случай с обратным вызовом прогресса, который никогда не вызывался при наступлении прогресса.
Что происходит, если вы измените GCL_CBWND_EXTRA класса окна?
