Microsoft-ui-xaml: 提案:自动调度属性更改事件到 UI 线程

创建于 2019-05-17  ·  3评论  ·  资料来源: microsoft/microsoft-ui-xaml

概括

允许从任何非 UI 线程引发通知更改的属性发生 UI 绑定

基本原理

绑定属性时,必须始终在 UI 线程上发出属性更改通知,否则会出现运行时异常。 这会导致 UI 渗入您的视图模型和模型,以便您可以在正确的线程上引发,这反过来又会阻止您使用 .NET Standard 库中的 INPC(除非您想进入 bait'n'switch) .

此外,您可能在一帧中多次更改属性,因此您可能跳到 UI 线程的次数可能比实际需要的次数多(只需将属性标记为“脏”,然后在下一个渲染通道。

所有这些都会导致明显额外的代码复杂性并且更容易出错。

这也导致了 WinUI 3.0 中的一个问题,因为我们现在有两个 UI 线程:旧版 UWP 和 WinUI 线程:我应该提高哪一个?

范围

  • 必须能够在任何线程上引发 INotifyPropertyChanged 和 INotifyCollectionChanged
  • 必须能够多次便宜地做到这一点,但只能触发一次更新(最后一次获胜)
  • 必须能够处理正在读取的属性以更新 UI。
  • 如果它已经在它上面,则避免切换到 UI 线程。

重要笔记

线程问题当然是有效的,但我不相信这最终真的是一个问题。 在 UI 更新之前触发多个 INPC 事件并不重要,因为只有最后一个事件才重要。 这与现有代码多次切换到 UI 线程没有什么不同。 一旦第一个切换到 UI 线程,该属性可能已经更新了很多次,因此最后一个获胜。
自然地,在读取值时需要一个短锁,以防止设置脏标志,因此如果在读取属性的同时更新属性,则在下一帧发生第二轮 UI 更新。
事实上,如果一个值例如从 false 变为 true,然后又变为 false,则 Dependency Property 已经足够智能,可以检测到该值没有改变,并且可以通过不因该属性而导致新的渲染传递来进行优化不变。

feature proposal team-Markup

最有用的评论

这是一个非常有效的问题,感谢您提出这个问题。 框架中对 DPs 的线程亲和性支持可能不是一个大问题,但对于 INPC 的实现者来说可能是一个很好的问题。

如果某些代码能够从非 UI 线程引发属性更改,这也意味着属性的支持代码可能会从后台线程更改。 它可以使用锁来保护它,但是双向绑定可能会成为一个问题,因为它们可能会使属性更改链死锁。

INPC还有一个最大的问题,就是事件发起时缺乏“当前”价值。 可能存在属性未正确同步的情况(例如, SelectedIndexItemsSource未同步更新并且SelectedIndex失去其值),或者由于由属性状态(例如文本框更改和正则表达式过滤器)。

这就带来了 INCC 的问题,即整个收藏品都需要得到适当的保护。 例如,您可能会引发一个引用已移动或不再存在的项目的事件。

我并不是说这个问题没有解决方案(肯定有),但是 IPNC 侦听器线程关联性更改不足以在接口的两端轻松解决这个问题。

所有3条评论

这是一个非常有效的问题,感谢您提出这个问题。 框架中对 DPs 的线程亲和性支持可能不是一个大问题,但对于 INPC 的实现者来说可能是一个很好的问题。

如果某些代码能够从非 UI 线程引发属性更改,这也意味着属性的支持代码可能会从后台线程更改。 它可以使用锁来保护它,但是双向绑定可能会成为一个问题,因为它们可能会使属性更改链死锁。

INPC还有一个最大的问题,就是事件发起时缺乏“当前”价值。 可能存在属性未正确同步的情况(例如, SelectedIndexItemsSource未同步更新并且SelectedIndex失去其值),或者由于由属性状态(例如文本框更改和正则表达式过滤器)。

这就带来了 INCC 的问题,即整个收藏品都需要得到适当的保护。 例如,您可能会引发一个引用已移动或不再存在的项目的事件。

我并不是说这个问题没有解决方案(肯定有),但是 IPNC 侦听器线程关联性更改不足以在接口的两端轻松解决这个问题。

WPF 已经解决了这个问题,所以也许只是从那里提取解决方案?

很好的建议。 我们为 CollectionChanged 事件执行此操作(有点意外......),我们应该能够为 NotifyPropertyChanged 执行相同操作。

此页面是否有帮助?
0 / 5 - 0 等级