为什么View在Prism复合wpf应用程序中第一次加载非常慢

时间:2009-11-06 00:14:24

标签: c# wpf performance prism

首次在区域内显示视图大约是5-10秒,并且我的Prism Composite WPF应用程序中的UI冻结了那段时间。在随后的时间中,View加载相对较快,没有任何UI冻结。 View由Devexpress WPF Grid控件组成,数据从SQL数据库中获取。我不认为这是Grid控件/绑定的问题,即使我使用网格控件删除绑定,View也需要几乎相同的时间将自身呈现为Region。

这是我用来将View加载到Shell中定义的Region中的代码:

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?

3 个答案:

答案 0 :(得分:3)

任何性能问题的答案始终是使用分析器。我们可以整天推测这个问题是什么,但没有确凿的事实,那只会是猜测。

您应该学会使用性能分析器。我推荐的是Redgate的ANTS Performance Profiler(http://www.red-gate.com/products/ants_performance_profiler/index.htm)。它易于使用,并为网站和程序中的初学者提供了很多帮助。

毫无疑问,这会告诉你你的瓶颈在哪里。

答案 1 :(得分:1)

最有可能的是,您的View正在将所有Dev Express和任何其他程序集加载到内存中并对其进行JIT。在使用Infragistics WPF控件时,我们在UI中看到类似的东西。

编辑:你无法避免这种情况。需要加载程序集,并在第一次运行时进行JIT。您可以尝试在启动期间预加载程序集pre-jitting the assemblies。您将无法在另一个UI线程上执行此操作,因为现在您的网格将由与容器不同的线程拥有,因此它将无法工作。

在数据网格中,您将看到花费大量时间绘制元素。通常情况下,网格控件将创建所有行和单元UI元素,并需要将这些元素绑定到您的数据。总而言之,将创建相当多的WPF UI元素,这些元素本身就占用了相当多的时间。

答案 2 :(得分:0)

可能是数据库连接设置需要一段时间,后续调用正在使用池&amp;因此不必重新打开连接,使它们更快。尝试分离数据库访问和实际工作,看看是否会减慢它的速度。

另外,为了避免UI冻结,您可以在单独的线程中执行所有初始化/加载,然后在最后激活回GUI线程以将其应用到适当的控件。