【问题标题】:Why a View is loading very slow for the first time in a Prism composite wpf application为什么视图在 Prism 复合 wpf 应用程序中第一次加载非常慢
【发布时间】:2009-11-06 00:14:23
【问题描述】:

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

这是我用来将 View 加载到 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) { }
}

这种行为背后的原因可能是什么?为什么 View 在第二次加载时几乎立即加载?这是否意味着即使在从 Region 中删除 View 之后,我的应用程序仍然持有对 View 的引用?

【问题讨论】:

  • 您是否尝试过在您的应用程序中使用分析器?

标签: c# wpf performance prism


【解决方案1】:

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

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

这将毫无疑问地告诉你你的瓶颈在哪里。

【讨论】:

  • 分析器的结果:InitializeComponent();在视图中第一次大约需要 3 秒,在随后的轮次中大约需要 100 毫秒左右。
  • 嗯,看来你有答案了。
【解决方案2】:

很可能,您的视图正在将所有 Dev Express 和任何其他程序集加载到内存中并 JIT 处理它们。使用 Infragistics WPF 控件时,我们在 UI 中看到了类似的情况。

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

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

【讨论】:

  • 当使用 wpf datagrid 中的 datagrid 时,我可以看到类似的(虽然不是那么大)。无论如何将 InitializeControls 方法移动到新的 UIThread 以便它不会阻塞我的应用程序的其余部分。
【解决方案3】:

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

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

【讨论】:

  • 即使我切断了数据库访问(只是一个没有任何绑定的空白网格),加载仍然需要 5-10 秒。
  • 你不能在单独的线程上创建 DependencyObjects...它被分配了错误的调度程序,你会得到错误。
猜你喜欢
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多