views:

382

answers:

5

Displaying a View inside a Region is about 5-10 seconds slow for the first time, and UI freezes for that period in my Prism Composite WPF application. In subsequent times View is loaded relatively faster without any UI freezing. View is composed of a Devexpress WPF Grid control and data is fetched from a SQL database. I don't think its an issue with the Grid control / binding though, even if I remove bindings with the grid control, View takes almost same time to render itself into a Region.

This is the code I use to load View into a Region defined inside the Shell:

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) { }
}

What could be the reason behind this behavior? Why View is getting loaded almost instantaneously when loaded for the second time? Does that mean even after removing View from the Region my application hold a reference to View?

A: 

Could be the database connection setup is taking a while, and subsequent calls are using the pool & hence don't have to re-open the connection, making them a lot quicker. Try separating out the database access and the actual work to see if that is slowing it down.

Also, to avoid the UI freezing, you could do all your initialization/loading in a seperate thread, and then right at the end fire back to the GUI thread to apply it to the appropriate controls.

mrnye
Even if I cut off database access (just a blank grid without any binding) it still take 5-10 seconds to load.
Raj
You can't create DependencyObjects on a separate thread... it gets assigned the wrong dispatcher and you get errors.
Anderson Imes
A: 

What lifetime manager are you using when you register your Views? Are you using the singleton one? If so, your object will still be around

serialhobbyist
No LifetimeManager object is passed to RegisterType<> method while registering the View. So they are not singleton. But still View will render faster from second time onwards.
Raj
A: 

Have you tryed using a profiler on your application?

Stephen
+2  A: 

The answer to any performance question is always to use a profiler. We could speculate all day about what the issue is, but without hard facts it would just be guesswork.

You should learn to use a performance profiler. The one I recommend is Redgate's ANTS Performance Profiler (http://www.red-gate.com/products/ants%5Fperformance%5Fprofiler/index.htm). It's easy to use and has a lot of help for beginners both on the website and in the program.

This will tell you without a doubt where your bottleneck is.

Anderson Imes
Results from profiler: InitializeComponent(); in the View takes around 3 seconds for the first time and in subsequent turns it takes ~100ms or so.
Raj
Well, it looks like you have your answer.
Anderson Imes
+1  A: 

Most likely, your View is loading all of the Dev Express and any other Assemblies into memory and JITting them. We see a similar thing in our UI when using the Infragistics WPF Controls.

Edit: You cannot really avoid this. The Assemblies need to be loaded and will be JITed on the first run. You can try pre-loading the Assemblies during start up and pre-jitting the assemblies. You won't be able to simply execute this on another UI thread, because now your grid will be owned by different thread than your container, so it will not work.

In a Data Grid, you will see a significant amount of time being spent drawing the elements. Usuaully what will happen is that the grid control will create all of the row and cell UI elements and will need to bind those to your data. All in all, a rather large number of WPF UI elements will be created which, inherently, takes up a decent amount of time.

siz
I could see similar (though not this large) when using datagrid from wpf datagrid. Is there anyway to move InitializeControls method to a new UIThread so that it wont block rest of my application.
Raj