Проблемы с производительностью при повторном открытии диалогового окна в wpf

У меня есть кнопка диалога запуска, которая создает модель представления окна и привязывает ее к окну (у него включена виртуализация пользовательского интерфейса). Запуск диалогового окна при первом нажатии занимает всего 1 секунду. Но если я открываю одно и то же диалоговое окно очень часто или один за другим, на заполнение источника данных сетки для следующей итерации уходит больше времени. если я даю некоторую паузу, а затем снова открываю окно, то это занимает всего около 1 или 2 секунд.

for first time populating the item source it take only 1 second:
next time populating the item source it takes  2 second
next time populating the item source it takes  3 second
next time populating the item source it takes  6 second
next time populating the item source it takes  8 second

Однако, если я вызываю GC.Collect(), что не рекомендуется, то заполнение источника данных сетки всегда занимает около 1 секунды. но призвание

Gc.Collect()
Gc.WaitForPendingFinalizer()
Gc.Collect()

стоило мне некоторого времени для каждой итерации.

Я знаю, что звонить GC.Collect не лучший вариант. Может ли кто-нибудь предложить, как я могу повысить производительность моего приложения.

Меня больше беспокоит пользовательская машина, поскольку моя машина имеет очень хорошую конфигурацию, тогда как пользовательская машина может быть не такой быстрой.


person Yogesh    schedule 08.02.2016    source источник
comment
Почему открытие диалогового окна каждый раз занимает больше времени? Возможно, вы загружаете слишком много данных. Рассмотрите возможность использовать разбиение на страницы (в сетке и в вашем SQL-запросе).   -  person Tim Schmelter    schedule 08.02.2016
comment
Может быть, вам нужно .Dispose некоторых ресурсов, прежде чем закрыть диалоговое окно?   -  person wildeyes    schedule 08.02.2016
comment
Тим, я тоже не понимаю. возможно я что-то упускаю, но не знаю что. Итак, ищем возможные ошибки   -  person Yogesh    schedule 08.02.2016
comment
Какой диалог вам нужно открывать очень часто или подряд?..   -  person Sayse    schedule 08.02.2016
comment
Это не реальный вариант использования, но группа тестирования проверяет нагрузочное тестирование или тестирование производительности. В реальном случае пользователь откроет его один раз, выполнит какую-то операцию, а затем закроет. но в моем случае они просто открывают и закрывают диалог подряд   -  person Yogesh    schedule 08.02.2016
comment
Данные Тима такие же, он загружает только объект 200 строк. Я бы подумал о виртуализации данных, если бы данные были действительно большими. но в первый раз для загрузки одних и тех же данных требуется всего 1 секунда, а после 5-7 итераций требуется больше времени   -  person Yogesh    schedule 08.02.2016
comment
Интересный вопрос, хотелось бы узнать причину. Легко ли воспроизвести, если я создам простое диалоговое приложение для показа? Кроме того, вы проверяете потребление памяти с каждым новым диалогом? просто дикая догадка, может ли замедление, вызванное подкачкой диска, из-за нехватки памяти?   -  person Peter    schedule 08.02.2016
comment
@Peter, посмотри мой комментарий к ответу, причина, указанная CharithJ, является наиболее возможной причиной.   -  person Yogesh    schedule 09.02.2016
comment
@YogeshJoshi Спасибо, что сообщили мне. Отличный вопрос и ответ!   -  person Peter    schedule 09.02.2016


Ответы (1)


Трудно точно определить проблему, не глядя на код. Однако, как правило, это может произойти по нескольким причинам.

  1. Он загружает больше данных (может быть, в два раза?) каждый раз. Вы указали, что он загружает только 200 записей каждый раз. Но убедитесь, что ваша логика верна, и она очищает предыдущие данные перед повторной публикацией.

  2. Убедитесь, что вы отписались от любых подписок на события. Иногда могут возникать скрытые события для предыдущих экземпляров сетки. Вы можете легко проверить это, поместив разрыв на четный дескриптор и проверив, срабатывает ли он более одного раза.

  3. Посмотрите на все экземпляры Disposable, которые вы создаете, и проверьте, правильно ли вы их утилизируете. Вероятно, вы не используете одноразовый экземпляр, и это может быть причиной того, что GC.Collect помогает.

  4. Я не совсем уверен в причастности здесь к виртуализации. Выполните тот же тест без виртуализации, чтобы убедиться, что причина не в ней.

person CharithJ    schedule 08.02.2016
comment
спасибо CharithJ, я понял, что это было из-за событий, на которые я не отписывался, но все же мне интересно, что это событие не поднималось автоматически, поскольку я поднимаю это событие вручную, выполняя только определенные действия. Так что это не должно было влиять на производительность. Теперь мне больше интересно узнать, влияет ли хранение такого количества обработчиков событий на производительность. Я не понимаю этого. с точки зрения памяти, они не занимали так много памяти. даже если они занимают больше, как это влияет на производительность. не могли бы вы подсказать мне об этом. - person Yogesh; 09.02.2016
comment
Нет необходимости занимать много памяти, чтобы вызвать проблемы с памятью. Может быть, вы имеете дело с большими объектами? Прочтите о simple-talk.com/dotnet/.net-framework/ Не забудьте удалить все одноразовые объекты непосредственно перед тем, как они выйдут из области действия. Реализуйте интерфейс IDisposable и отпишитесь от любых событий в методе Dispose. - person CharithJ; 09.02.2016
comment
большое спасибо, что поделились этой статьей, это именно то, что я искал - person Yogesh; 09.02.2016