Wpf 使用被动扩展时无法填充对象层次结构

Wpf 使用被动扩展时无法填充对象层次结构,wpf,prism,system.reactive,Wpf,Prism,System.reactive,我不熟悉被动扩展,所以我不知道在这个问题中什么是重要的 我有一个WPF应用程序,它在树状视图中显示了5个层次结构。该体系结构使用Prism和MVVM。为treeView构建源数据的代码大约需要一分钟来为三个顶级节点构建对象层次结构。以下是我的MVVM的一些细节: private ObservableCollection<IDxStudioInstanceDto> _instanceList = null; public ObservableCollection<IDxS

我不熟悉被动扩展,所以我不知道在这个问题中什么是重要的

我有一个WPF应用程序,它在树状视图中显示了5个层次结构。该体系结构使用Prism和MVVM。为treeView构建源数据的代码大约需要一分钟来为三个顶级节点构建对象层次结构。以下是我的MVVM的一些细节:

  private ObservableCollection<IDxStudioInstanceDto> _instanceList = null;
  public ObservableCollection<IDxStudioInstanceDto> InstanceList {
     get { return _instanceList; }
     set {
        _instanceList = value;
        OnPropertyChanged("InstanceList");
     }

  private void DisplayDataFetch() {
     InstanceList = _businessFacade.InstanceListFetch();

     //foreach(var instance in InstanceList) {
     //   _businessFacade.InstanceHierarchyFetch(instance);
     //}

     var query = from instance in InstanceList
                 select instance;
     var observableSequence = query.ToObservable().SubscribeOn(Scheduler.TaskPool).ObserveOnDispatcher();
     _subscribeInstanceHierarchy = observableSequence.Subscribe(instance => _businessFacade.InstanceHierarchyFetch(instance));
  }
剩下的代码,或者是注释过的foreach循环,或者下面的被动扩展代码,用子层次结构填充每个顶级节点。两者都使用同一组调用来构建层次结构。我希望通过顶级节点快速加载treeView,然后在完成剩余的子层次结构后,将其添加到显示的treeView中

如果我在UI线程上运行整个流程,用带注释的foreach循环替换反应式扩展代码,则treeView会按预期显示层次结构。尽管UI线程被阻塞了大约一分钟

如果我运行被动扩展代码,UI线程会被阻塞大约一分钟,树的顶级节点是“裸”的,缺少整个子层次结构

我尝试了Scheduler.ThreadPool并删除了ObserveSequence的ObserveOnDispatch()部分,但没有成功


有什么想法吗?

由于您的观察者/订阅者(
实例=>\u businessFacade.InstanceHierarchyFetch(实例)
)正在调度程序上运行,UI被阻止

我建议您重构
InstanceHierarchyFetch
以返回结果,而不要对传入的
IDxStudioInstanceDto
实例进行变异。然后您可以将查询更改为以下内容:

var query = from instance in InstanceList.ObserveOn(Scheduler.TaskPool)
            let hierarchy = FetchHierarchyFor(instance.Key)
            select new {instance, hierarchy};

query
  .ObserveOnDispatcher()
  .Subscribe(tuple => tuple.instance.UpdateHierarchy(tuple.hierarchy);
这样,抓取将在后台线程中运行,而实例的变异将在UI线程中运行,以便更好地使用WPF和数据绑定

关于原始代码,您应该注意以下几点:

  • SubscribeOn
    不会做您认为它会做的事情。读一读。您想要使用的是
    ObserveOn
  • {
    from instance in InstanceList select instance
    }等同于{
    InstanceList
    }。这是多余的

由于您的观察者/订阅者(
实例=>\u businessFacade.InstanceHierarchyFetch(实例)
)正在调度程序上运行,UI被阻止

我建议您重构
InstanceHierarchyFetch
以返回结果,而不要对传入的
IDxStudioInstanceDto
实例进行变异。然后您可以将查询更改为以下内容:

var query = from instance in InstanceList.ObserveOn(Scheduler.TaskPool)
            let hierarchy = FetchHierarchyFor(instance.Key)
            select new {instance, hierarchy};

query
  .ObserveOnDispatcher()
  .Subscribe(tuple => tuple.instance.UpdateHierarchy(tuple.hierarchy);
这样,抓取将在后台线程中运行,而实例的变异将在UI线程中运行,以便更好地使用WPF和数据绑定

关于原始代码,您应该注意以下几点:

  • SubscribeOn
    不会做您认为它会做的事情。读一读。您想要使用的是
    ObserveOn
  • {
    from instance in InstanceList select instance
    }等同于{
    InstanceList
    }。这是多余的

我解决了“裸”顶级节点的问题。在某些子对象上缺少INotifyPropertyChanged是一个错误。现在,它显示完成处理后的完整树。但是,它仍然会阻止UI线程,直到完成。顶级节点的初始列表在可用时不显示,然后在处理结束时,所有内容都会以完全形式突发到表单上。我希望显示顶级节点的初始列表,然后在每个线程上的处理完成时填写。我是否没有正确地实现SubscribeOn和ObserveOnDispatch?顶级节点初始列表的显示现在正在工作,这是一个检测问题。在填充每个顶级节点的子节点时,UI仍被阻塞大约一分钟。所有顶级节点都是裸体的,直到所有节点的子节点处理完成,然后它们一起显示。为什么不在每一个节点完成时填充呢?我解决了“裸”顶级节点的问题。在某些子对象上缺少INotifyPropertyChanged是一个错误。现在,它显示完成处理后的完整树。但是,它仍然会阻止UI线程,直到完成。顶级节点的初始列表在可用时不显示,然后在处理结束时,所有内容都会以完全形式突发到表单上。我希望显示顶级节点的初始列表,然后在每个线程上的处理完成时填写。我是否没有正确地实现SubscribeOn和ObserveOnDispatch?顶级节点初始列表的显示现在正在工作,这是一个检测问题。在填充每个顶级节点的子节点时,UI仍被阻塞大约一分钟。所有顶级节点都是裸体的,直到所有节点的子节点处理完成,然后它们一起显示。为什么他们不在每一个都完成的时候填写呢?谢谢你的信息,我会调查这一切的。太好了。。。!,谢谢使用你的答案让我在使用Rx的道路上走得更远。谢谢你提供的信息,我会调查所有这些。亲爱的。。。!,谢谢使用你的答案将我推向了使用Rx的更远的道路。