在Prism(MEF v.5)wpf应用程序中,View首次加载速度非常慢

时间:2016-03-09 18:01:18

标签: c# wpf performance navigation prism

首次加载视图需要2-5秒依赖视图内容。但第二次立即加载。 最重的"重#34; content只有一个RadGridView,但是在初始化期间已经从数据库加载了程序集和所有数据(空数据)。

private void Navigate(NavigateInfo info)
    {
        _workingNavigateInfo = info;
        _regionManager.RequestNavigate(MAIN_REGION_NAME, new Uri(info.NextViewName, UriKind.Relative), NavigationCompleted);
    }

我在应用初始化过程中初始化视图和视图模型

var jobB = _container.GetExportedValue<ViewB>();
var jobBModel = _container.GetExportedValue<ViewBModel>();
jobB.DataContext = jobBModel;

这是我的ViewModels

的一个例子
[Export]
[PartCreationPolicy(CreationPolicy.Shared)]
public class ViewBModel : NavigationViewModel
{
    private readonly IRegionManager _regionManager;
    private readonly NavigationService<ViewB> _navigation;

    [ImportingConstructor]
    public ViewBModel(IRegionManager regionManager)
    {           
        this._regionManager = regionManager;
        this.GotoA = new DelegateCommand<object>(this.ExecuteGotoA);
        this.GotoBack = new DelegateCommand<object>(this.ExecuteGotoBack);            
        _navigation = new NavigationService<ViewB>(regionManager);
    }

    public DelegateCommand<object> GotoA { get; private set; }
    public DelegateCommand<object> GotoBack { get; private set; }

    private void ExecuteGotoA(object notused)
    {
        _navigation.NavigateToPage("ViewA");
    }

    private void ExecuteGotoBack(object notused)
    {
        _navigation.NavigateBack();
    }
}

和查看

 [Export] 
public partial class ViewB : UserControl
{
    public ViewB()
    {
        InitializeComponent();
    }
}

由于导航在没有[导出(&#34; ViewB&#34;,typeof(ViewB))]属性的情况下无效,我创建了一个新的MefServiceLocatorAdapter以避免找不到错误

public class MyMefServiceLocatorAdapter : MefServiceLocatorAdapter
{
    CompositionContainer _container;
    public MyMefServiceLocatorAdapter(CompositionContainer container): base(container)
    {
        _container = container;
    }

    protected override object DoGetInstance(Type serviceType, string key)
    {
        IEnumerable<Lazy<object, object>> exports = this._container.GetExports(serviceType, null, key).ToList();

        if ((exports != null) && (exports.Count() > 0))
        {
            // If there is more than one value, this will throw an InvalidOperationException, 
            // which will be wrapped by the base class as an ActivationException.
            return exports.Single().Value;
        }

        var extended = this._container.Catalog.Where(x => x.ExportDefinitions.Any(y => y.ContractName.EndsWith(key))).ToList();
        if ((extended != null) && (extended.Count() > 0))
        {
            var type = ReflectionModelServices.GetPartType(extended.Single()).Value;
            var serviceTypeIdentity = AttributedModelServices.GetTypeIdentity(type);
            return _container.GetExports(serviceType, null, serviceTypeIdentity).First().Value;
        }

        throw new ActivationException(FormatActivationExceptionMessage(new CompositionException("Export not found"), serviceType, key));
    }
}

我发现了一篇很好的文章,如何让导航更快Navigate faster with Prism and WPF 但是id并没有给我任何改进。 我使用了性能分析器Redgate的ANTS,它向我展示了在第一次导航时方法LoadContent和RequestCanNavigateFromOnCurrentlyActiveViewModel(不明白为什么)运行1秒,但第二次花了不到1毫升。 我尝试在初始化期间执行LoadContent并添加到区域,但我可以加载并将所有视图添加到区域。不幸的是,这个策略没有给我任何改进。

2 个答案:

答案 0 :(得分:2)

由于Telerik网格,它第一次运行缓慢的原因。一旦网格被渲染并且所有组件都被加载,第二次加载就会快得多。我几乎可以向您保证,如果您从视图中删除Telerik网格并运行您的应用程序,视图将加载得更快。

答案 1 :(得分:0)

我和Brian在此。你正在使用Telerik,如果你使用DevExpress的类似产品(我在这里谈到经验),你会遇到同样的事情,它与Prism无关。