У меня есть приложение WPF, которое отображает изображения в сетке. Пользователь имеет возможность быстро прокручивать изображения, перемещая мышь и щелкая левой кнопкой мыши. Это означает, что множество изображений меняется с большой скоростью.
Я заметил снижение производительности для сеток размером 24 и 40 элементов (которые являются самыми большими). Я определил, что причиной замедления было создание большого количества мусора, что вызвало множество блокировок сборок мусора gen0 и gen1. Уменьшив количество выделений, я смог улучшить производительность примерно с 10 до 25 кадров в секунду.
Все еще не полностью удовлетворенный этим, я проанализировал еще немного и заметил, что создается огромное количество объектов Action, которые намного превышают все другие выделяемые типы. При прокрутке я получаю около 50000 действий в секунду.
Я отследил это с помощью профилировщика памяти, и причиной является одно событие PropertyChanged, которое срабатывает каждый раз, когда изображение должно измениться. Это вызывает внутреннюю регистрацию и отмену регистрации некоторых событий, этот диспетчер событий использовал класс ReaderWriterLockWrapper. Действительно, каждый раз, когда осуществляется доступ к свойствам WriteLock или ReadLock, будет выделяться Action, как показано в справочном источнике:
CallWithNonPumpingWait(()=>{_rwLock.EnterWriteLock();});
Я заметил, что код такой, начиная с версии фреймворка 4.7. Это предназначено? Одно это вызывает в моем приложении экземпляры Action объемом 16 МБ, когда я непрерывно прокручиваю в течение 8 секунд. Кроме того, как я понимаю, эта лямбда может быть просто членом экземпляра.
Мой вопрос: есть ли способ избежать этого, возможно, подключив какое-либо другое поведение для этого определенного события, но я предполагаю, что это не так. Думаю, вы правы, мне, наверное, стоит спросить об этом на форумах Microsoft.





Эта проблема решена в .NET 4.8 путем включения EnableWeakEventMemoryImprovements.
Вы тщательно проанализировали проблему, но каков ваш настоящий вопрос к сообществу StackOverflow? Вы не спрашиваете нас, был ли код в справочном источнике намеренно написан авторами .NET Framework?