Не удается заполнить иерархию объектов при использовании реактивных расширений - PullRequest
1 голос
/ 20 марта 2012

Я новичок в расширениях 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));
  }

Метод MVVM с именем 'DisplayDataFetch' делает две вещи.Он загружает узлы верхнего уровня только в ObservableCollection.

     InstanceList = _businessFacade.InstanceListFetch();

Оставшийся код, либо закомментированный цикл foreach, либо код Reactive Extension ниже этого, заполняет каждый узел верхнего уровня дочерней иерархией.,Оба используют один и тот же набор вызовов для построения иерархии.Я ожидал, что treeView загрузится быстро с узлами верхнего уровня, а затем, когда остальные дочерние иерархии будут завершены, будут добавлены в отображаемое treeView.

Если я запускаю весь процесс в потоке пользовательского интерфейса, подставляяв цикле foreach с комментариями для кода Reactive Extension treeView отображает иерархию, как и ожидалось.Хотя поток пользовательского интерфейса блокируется примерно на одну минуту.

Если я запускаю код Reactive Extension, поток пользовательского интерфейса блокируется примерно на минуту, а узлы верхнего уровня дерева «голые», пропуская весь дочерний элемент.Иерархия.

Я безуспешно пытался Scheduler.ThreadPool и удалял часть ObserveOnDispatch () из observableSequence.

Есть идеи?

1 Ответ

1 голос
/ 23 марта 2012

Пользовательский интерфейс заблокирован, потому что ваш наблюдатель / подписчик (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);

Таким образом, выборка будет выполняться в фоновом потоке, в то время как изменение ваших экземпляров будет выполняться в потоке пользовательского интерфейса, чтобыиграйте хорошо с WPF и привязкой данных.

Несколько вещей, которые вы должны заметить в своем исходном коде:

  • SubscribeOn не делает то, что вы думаете, что делает.Читайте об этом.Вы хотели использовать ObserveOn.
  • {from instance in InstanceList select instance} эквивалентно {InstanceList}.Это избыточно.
...