Как я обновляю ObservableCollection через рабочий поток?

Я имею ObservableCollection<A> a_collection; Набор содержит 'n' объекты. Каждый объект взгляды как это:

public class A : INotifyPropertyChanged
{

    public ObservableCollection<B> b_subcollection;
    Thread m_worker;
}

В основном это все соединено проводом до WPF listview + управление представлением деталей, которое показывает b_subcollection из выбранного пункта в отдельном listview (привязка с 2 путями, обновления на propertychanged и т.д.).

Проблема собралась для меня, когда я начал реализовывать поточную обработку. Вся идея состояла в том, чтобы иметь целое a_collection используйте это - рабочий поток, чтобы "сделать работу" и затем обновить их соответствующее b_subcollections и имейте шоу gui результаты в режиме реального времени.

Когда я попробовал его, я получил исключение, говоря, что только поток Диспетчера может изменить ObservableCollection, и работа остановилась.

Кто-либо может объяснить проблему, и как обойти ее?

71
задан ASh 24 October 2019 в 12:27
поделиться

1 ответ

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

Чтобы заполнить коллекцию из фоновой резьбы, пока элементы управления связаны с ним, вы, вероятно, должны придеться создать собственную коллекцию типа с нуля, чтобы решить это. Существует более простая опция, которая может работать для вас, хотя.

Опубликуйте вызовы добавления на тему пользовательского интерфейса.

public static void AddOnUI<T>(this ICollection<T> collection, T item) {
    Action<T> addMethod = collection.Add;
    Application.Current.Dispatcher.BeginInvoke( addMethod, item );
}

...

b_subcollection.AddOnUI(new B());

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

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

Класс класс Class реализует шаблон, который позволяет сообщать о прогрессе через его метод отчетности в течение фоновой операции. Прогресс зарегистрирован на потоке пользовательского интерфейса через прогрессированное событие. Это может быть другой вариант для вас.

67
ответ дан 24 November 2019 в 12:51
поделиться
Другие вопросы по тегам:

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