Почему представление загружается очень медленно в первый раз в приложении Prism Composite wpf

Отображение вида внутри региона в первый раз занимает около 5-10 секунд медленно, и пользовательский интерфейс на этот период зависает в моем приложении Prism Composite WPF. В последующие разы View загружается относительно быстрее без зависания пользовательского интерфейса. Представление состоит из элемента управления Devexpress WPF Grid, а данные извлекаются из базы данных SQL. Я не думаю, что это проблема с элементом управления / привязкой сетки, хотя, даже если я удалю привязки с помощью элемента управления сеткой, View потребуется почти столько же времени, чтобы отобразить себя в регионе.

Это код, который я использую для загрузки представления в область, определенную внутри оболочки:

public Action<MenuModel> LoadViewRequest { get; set; }

public SyncController(IUnityContainer container, IEventAggregator eventAggregator, IRegionManager regionManager)
{
    this.container = container;
    this.eventAggregator = eventAggregator;
    this.regionManager = regionManager;
    this.LoadViewRequest = (menuItem) => { LoadRequestedView(menuItem); };
    this.eventAggregator.GetEvent<ViewRequestedEvent>().Subscribe(LoadViewRequest, ThreadOption.UIThread, true, i => i.Module == "Sync");
}

private void LoadRequestedView(MenuModel menuItem)
{
    try
    {
        IViewModel viewModel = this.container.Resolve<SynchronizeViewModel>();
        this.regionManager.Regions["ViewRegion"].Add(viewModel.View);
        this.regionManager.Regions["ViewRegion"].Activate(viewModel.View);
        viewModel.DisplayName = menuItem.Description;
        this.eventAggregator.GetEvent<ViewNotificationEvent>().Publish(menuItem.Description);
    }
    catch (ResolutionFailedException) { }
}

В чем может быть причина такого поведения? Почему View загружается почти мгновенно при второй загрузке? Означает ли это, что даже после удаления View из региона мое приложение содержит ссылку на View?


person Raj    schedule 06.11.2009    source источник
comment
Вы пробовали использовать профилировщик в своем приложении?   -  person Steoates    schedule 06.11.2009


Ответы (3)


Скорее всего, ваше представление загружает все Dev Express и любые другие сборки в память и выполняет их JIT. Мы видим похожую вещь в нашем пользовательском интерфейсе при использовании элементов управления Infragistics WPF.

Изменить: вы действительно не можете этого избежать. Сборки должны быть загружены, и они будут JIT-обработаны при первом запуске. Вы можете попробовать предварительно загрузить сборки во время запуска и предварительно настроить сборки. Вы не сможете просто выполнить это в другом потоке пользовательского интерфейса, потому что теперь ваша сетка будет принадлежать другому потоку, чем ваш контейнер, поэтому это не будет работать.

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

person Szymon Rozga    schedule 07.11.2009
comment
Я мог видеть подобное (хотя и не такое большое) при использовании datagrid из wpf datagrid. Есть ли способ переместить метод InitializeControls в новый UIThread, чтобы он не блокировал остальную часть моего приложения. - person Raj; 07.11.2009

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

Вы должны научиться использовать профилировщик производительности. Я рекомендую Redgate ANTS Performance Profiler (http://www.red-gate.com/products/ants_performance_profiler/index.htm). Он прост в использовании и очень помогает новичкам как на веб-сайте, так и в программе.

Это без сомнения скажет вам, где находится ваше узкое место.

person Anderson Imes    schedule 06.11.2009
comment
Результаты профилировщика: InitializeComponent (); в обзоре в первый раз занимает около 3 секунд, а в последующих ходах - около 100 мс. - person Raj; 07.11.2009
comment
Что ж, похоже, у тебя есть ответ. - person Anderson Imes; 07.11.2009

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

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

person mike    schedule 06.11.2009
comment
Даже если я отключу доступ к базе данных (просто пустая сетка без привязки), загрузка все равно займет 5-10 секунд. - person Raj; 06.11.2009
comment
Вы не можете создавать DependencyObjects в отдельном потоке ... ему назначается неправильный диспетчер, и вы получаете ошибки. - person Anderson Imes; 06.11.2009