Обновление ObservableCollection в отдельном потоке

В приложении WPF ObservableCollection переполнен и обновляется LINQ к SQL-запросам. Тогда объекты пользовательского интерфейса обновляются с помощью значений от этого ObservableCollection.

Действительно ли это возможно и разумно, что операции обновления этого ObservableCollection LINQ к SQL-запросам выполнялись в отдельном потоке?

Если да, будет, в этом случае, это - один и тот же экземпляр этого ObservableCollection? (Я имею в виду, если это не будет тот же для принимающих значений от LINQ datacontext и того для предоставления значений для обновления UI, тогда я не буду в состоянии обновить UI),

13
задан rem 20 January 2010 в 20:23
поделиться

3 ответа

со встроенным ClassableCollection класс, вы можете Измените содержимое от отдельного потока, если UI связан с коллекцией, он бросает NotSupportedException (но изменение уведомления о свойствах предметов сбора работает). Я написал asyncobservableCollection класс [1111] для обработки этого случая. Он работает, вызывая обработчики событий на контексте синхронизации UI

26
ответ дан 1 December 2019 в 17:27
поделиться

Попытка понять ваш вопрос здесь:

Scenario 1
1. LINQ to SQL retrieves data set from database and adds to ObservableCollection A.
2. Periodically, more data is retrieved from database and added to A. Old data is removed from A.

Scenario 2
1. LINQ to SQL retrieves data set from database and adds to ObservableCollection A.
2. Periodically, data in A is updated with new data from database (no add/remove).

со сценарием 1, вам придется использовать нить пользовательского интерфейса. Тема пользовательского интерфейса владеет наблюдателем для наблюдения, и вы получите исключение, если вы попытаетесь использовать его в другом потоке.

С сценарием 2, палец вверх. До тех пор, пока вы не пытаетесь добавить или удалить элементы из самой коллекции, вы можете обновить товар столько, сколько хотите в фоновом потоке.

2
ответ дан 1 December 2019 в 17:27
поделиться

В нашем приложении у нас есть TreeView, связанный с ObservableCollection, который мы регулярно обновляем в фоновом потоке, запрашивая данные из нашего хранилища. Он работает идеально!

Упс. Меня неправильно информировали =))

Правильно, на самом деле мы подклассифицируем ObservableCollection и переопределяем метод OnCollectionChanged, чтобы избежать исключения для чтения UI в перекрестном потоке. Мы используем это решение :

public class MTObservableCollection<T> : ObservableCollection<T>
{
   public override event NotifyCollectionChangedEventHandler CollectionChanged;
   protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   {
      var eh = CollectionChanged;
      if (eh != null)
      {
         Dispatcher dispatcher = (from NotifyCollectionChangedEventHandler nh in eh.GetInvocationList()
                 let dpo = nh.Target as DispatcherObject
                 where dpo != null
                 select dpo.Dispatcher).FirstOrDefault();

        if (dispatcher != null && dispatcher.CheckAccess() == false)
        {
           dispatcher.Invoke(DispatcherPriority.DataBind, (Action)(() => OnCollectionChanged(e)));
        }
        else
        {
           foreach (NotifyCollectionChangedEventHandler nh in eh.GetInvocationList())
              nh.Invoke(this, e);
        }
     }
  }
}

Без этого переопределения вы бы получили исключение типа

System.NotSupportedException : This тип CollectionView не поддерживать изменения в его SourceCollection из нити отличается от нити Диспетчера.

Теперь единственная проблема, которая у нас есть - это позиция выбранного элемента, в некоторых случаях, если текущий выбранный элемент удаляется из коллекции, TreeView перемещает выделение на следующий элемент (что вызывает некоторые другие ненужные действия пользовательского интерфейса в нашем приложении). Но это небольшая проблема.

6
ответ дан 1 December 2019 в 17:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: