【问题标题】:INotifyPropertyChanged: what happens behind the scene?INotifyPropertyChanged:幕后发生了什么?
【发布时间】:2010-09-04 01:06:44
【问题描述】:

在 WPF 中,我们有两个线程(至少):渲染和 UI 线程。当我在某些属性更改时引发事件 OnNotifyPropertyChanged 时,它会在 UI 线程上引发。需要将此信息分派到 WPF 渲染线程进行重新渲染。我假设它是以同步方式完成的( Dispatcher.Invoke ),但它是如何工作的?

如果我为同一个数据结构引发多个 OnNotifyPropertyChanged 事件,而没有锁定对已引发这些事件的该数据结构的访问器属性的访问,我是否会创建潜在的竞争条件?我已经看到来自 WPF 的臭名昭著的“集合已修改;枚举操作可能无法执行”异常,因此看起来 WPF 异步处理这些事件。我误解了例外吗?谢谢!

【问题讨论】:

  • 你为什么不发布一个样本来重新创建这个?比如显示一些你经常从一些 DispatcherTimer 事件中更改的集合。

标签: wpf multithreading inotifypropertychanged


【解决方案1】:

异常“集合已修改;枚举操作可能无法执行”与 WPF 无关,当您使用 foreach 对集合进行迭代时,它会从 IEnumerator 引发,同时该集合以某种方式发生了更改(添加/删除/修改)。 (例如:http://social.msdn.microsoft.com/forums/en/netfxbcl/thread/7ce02724-2813-4f7d-8f3c-b1e3c1fd3019/) .

除此之外,我从未遇到过由多个同时调用 PropertyChanged 事件引起的异常。

【讨论】:

  • 重点是该集合是由 WPF 而不是我的代码迭代的。当我打开第一次机会异常时,我发现它在 .NET 中失败了
  • 我最好的猜测是它正在发生,因为您在加载 xaml 期间修改了集合。绑定正在尝试迭代集合以在您的 ItemsControl 上填充它,同时您正在修改它。尝试同步它。
【解决方案2】:

希望当你引用两个线程时,你是在引用

  1. 渲染线程
  2. UI 线程。

是的,你是对的,更新是异步的

看看http://msdn.microsoft.com/en-us/magazine/cc163328.aspx

【讨论】:

  • 大师,哪里说 WPF 异步处理 NotifyPropertyChanged 事件?
【解决方案3】:

您是否在非 UI 线程上对自己进行任何处理?我很确定您绑定到的任何枚举的迭代都将在 UI 线程上完成,因此如果在您引发事件后,您的应用程序中的其他人修改了集合,您将收到此异常。

这个问题不应该是由渲染线程迭代你的集合引起的,因为它从来没有这样做过。

【讨论】:

    猜你喜欢
    • 2011-10-19
    • 2011-07-12
    • 1970-01-01
    • 2018-03-29
    • 2019-06-05
    • 1970-01-01
    • 2010-09-06
    • 2018-12-05
    • 2016-02-23
    相关资源
    最近更新 更多