我有一个WPF应用程序,其中包含许多支持INotifyProprtyChange接口的类。此类的属性从不同的线程以很高的速度更改,问题是在某些情况下应用程序 UI 线程挂起,与 UI 线程一起,其他具有代码调用 PropertyChange 的线程在尝试更新属性时也会挂起。
我对 Windbg 进行了死锁检查,但它无法检测到任何内容。现在我查看了持有锁的线程的堆栈跟踪,我总是看到至少一个相同或不同的线程具有
00000000002d0ab8 000000007712908a [HelperMethodFrame_1OBJ: 00000000002d0ab8] System.Threading.SynchronizationContext.WaitHelper(IntPtr[], Boolean, Int32)
00000000002d13b0 000000007712908a [GCFrame: 00000000002d13b0]
00000000002d16c8 000000007712908a [HelperMethodFrame_1OBJ: 00000000002d16c8] System.Threading.ReaderWriterLock.AcquireReaderLockInternal(Int32)
00000000002d17f0 000007fef1bcf1a0 MS.Internal.ReaderWriterLockWrapper.get_ReadLock()
00000000002d1830 000007fef1ba8d44 System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(System.Object, System.ComponentModel.PropertyChangedEventArgs)
和另一个
000000001f64d138 000000007738186a [HelperMethodFrame_1OBJ: 000000001f64d138] System.Threading.ReaderWriterLock.AcquireReaderLockInternal(Int32)
000000001f64d260 000007fef1bcf1a0 MS.Internal.ReaderWriterLockWrapper.get_ReadLock()
000000001f64d2a0 000007fef1ba8d44 System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(System.Object, System.ComponentModel.PropertyChangedEventArgs)
所以它看起来像属性更改事件管理器等待某个线程完成,而其他线程等待获取锁定?
现在我很难弄清楚为什么会发生这种情况,因为它是零星的,通常在有许多属性更改事件时发生。从我所看到的应用程序中不调用属性更改的其他线程继续正常运行。
据我所知,PropertyNotifyChanged 仅在 UI 线程中受支持。
只是猜测。在更大的环境中,一个问题很容易悄悄发生:2个属性无休止地相互更新。道具 A 的二传手调用道具 B 的二传手,而道具 B 又再次调用 A 的二传手。通常当然没有描述的那么明显,但值得一看。