我是Reactive扩展的新手,所以我不知道在问题中描述什么是重要的。
我有一个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));
}
名为"DisplayDataFetch"的MVVM方法做两件事。它只将顶级节点加载到ObservableCollection中。
InstanceList = _businessFacade.InstanceListFetch();
剩下的代码,要么是注释的foreach循环,要么是下面的Reactive Extension代码,用子层次结构填充每个顶级节点。两者都使用相同的调用集来构建层次结构。我希望用顶级节点快速加载treeView,然后在完成剩余的子层次结构后,将其添加到显示的treeView中。
如果我在UI线程上通过用注释的foreach循环替换Reactive Extension代码来运行整个过程,那么treeView将按预期显示层次结构。尽管UI线程被阻塞了大约一分钟。
如果我运行Reactive Extension代码,UI线程会被阻塞大约一分钟,并且树的顶级节点是"裸的",缺少整个子层次结构。
我尝试过Scheduler.ThreadPool并删除ObserveOnDispatch()部分的observeSequence,但没有成功。
有什么想法吗?
UI被阻止,因为您的观察者/订阅者(instance => _businessFacade.InstanceHierarchyFetch(instance)
)正在调度器上运行。
我建议您重构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
}。这是多余的