OnPropertyChanged导致大量的动作分配

时间:2018-08-11 11:36:33

标签: c# .net wpf

我有一个WPF应用程序,可以在网格中显示图像。用户可以通过在单击鼠标左键的同时移动鼠标来快速滚动浏览图像。因此,这意味着有很多图像在快速变化。

我注意到24个和40个元素大小的网格(最大)的性能下降。我发现减速的原因是大量垃圾被创建,从而导致大量的gen0和gen1垃圾收集受阻。通过减少分配量,我可以将性能从大约10 fps提升到25 fps。

仍然对此不完全满意,我进行了更多分析,发现有大量Action对象正在生成,远远超过了所有其他分配的类型。滚动时,我每秒获得约50000个动作分配。

我使用内存探查器进一步跟踪了此事件,原因是一个PropertyChanged事件,该事件在每次图像更改时都会触发。这在内部导致一些事件被注册和注销,该事件管理器使用类ReaderWriterLockWrapper。实际上,每次访问WriteLock或ReadLock属性时,都会分配一个Action,如参考源所示:

https://referencesource.microsoft.com/#WindowsBase/Shared/MS/Internal/ReaderWriterLockWrapper.cs,7553fcec2d50ae8a,references

CallWithNonPumpingWait(()=>{_rwLock.EnterWriteLock();});

我注意到从4.7版开始,代码就是这种方式。这是故意的吗?当我连续滚动8秒时,仅此一项就在我的应用程序中导致了16MB的Action实例。另外,按照我的看法,此lambda可能只是实例成员。

1 个答案:

答案 0 :(得分:0)

.NET 4.8通过启用EnableWeakEventMemoryImprovements解决了该问题