82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
|
1 | |
Заполнение коллекции из разных потоков24.09.2019, 15:52. Показов 11908. Ответов 23
Метки нет Все метки)
(
Добрый день.
Что я могу использовать вместо удобной ObservableCollection<T>, если мне надо добавлять данные из разных потоков?
0
|
|
24.09.2019, 15:52 | |
Ответы с готовыми решениями:
23
Обезопасить доступ к коллекции из разных потоков Заполнение TreeView из разных потоков Одновременный доступ к коллекции из двух потоков Заполнение коллекции из БД |
![]() 1829 / 1337 / 427
Регистрация: 10.06.2011
Сообщений: 2,124
|
||||||
24.09.2019, 18:12 | 2 | |||||
Можно оборачивать критическую секцию оператором lock. Такой вариант почему вам не подходит?
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
|
24.09.2019, 19:00 [ТС] | 3 |
Я вообще никаких вариантов не знаю =(
Подходит, почему нет. А можно побольше кода, а то не очень понятно по обрывку. Я решил использовать BlockingCollection<T> вместо ObservableCollection<T>, это плохое решение?
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
|
24.09.2019, 19:27 [ТС] | 5 |
Есть у меня форма, там есть DataGrid который привязан к ObservableCollection<T>
Все было хорошо, но случилось так, что ObservableCollection<T> надо заполнять с двух потоков, а она не заполняется, вот я и думаю, что делать. А её никак нельзя обернуть в INotifyColletionChanged? Может мне лучше пример кода написать, чтобы видно было чего да как?
0
|
Модератор
![]() |
|
24.09.2019, 19:53 | 6 |
ObservableCollection<T> это коллекция с реализацией INСC. Из Net коллекций, по-моему, она единственная. Она сама и, конечно, её наследники.Проблема использования ObservableCollection<T> в том, что INCC в WPF не приводится к основному потоку и при её обновлении из другого потока будет исключение.Поэтому использовать ObservableCollection<T> (которая непосредственно привязана в WPF View) в Модели многопоточного приложения нельзя.Модель (или Модели) должны создать у себя обычную коллекцию. Если одна для нескольких потоков, то с защитой от конфликтов. А при внесении изменений в эту коллекцию сообщать через события в VM о том какие изменения произошли. Передача данных в VM происходит в DTO типах в самой простой реализации без интерфейса INPC. VM ловит событие и данные в DTO типах, конвертирует их в типы для отображения (уже с INPC) и в ОСНОВНОМ потоке вносит нужные изменения в коллекцию типа ObservableCollection<T> .Чипс, сожалею что так сложно. Но проще - чревато исключениями, багами и т.д.
1
|
![]() 1829 / 1337 / 427
Регистрация: 10.06.2011
Сообщений: 2,124
|
||||||
24.09.2019, 20:10 | 7 | |||||
Если код выполняется не в UI потоке, то тогда нужно добавление элементов в коллекцию сделать в UI потоке
Пример с испоьлзованием ReactiveUI:
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
||||||||||||||||
25.09.2019, 12:16 [ТС] | 8 | |||||||||||||||
Млин фигня какая-то!
Теперь из разных потоков нормально добавляется в ObservableCollection<T> или я не из разных потоков добавляю? Program
Number
MainWindowVM
Добавлено через 1 минуту Нормально, я Вас понял. Добавлено через 1 минуту или нельзя с разных потоков наполнять коллекцию которая ??? А в не привязанную набивай сколько хочешь?
0
|
Модератор
![]() |
|
25.09.2019, 12:47 | 9 |
Да.
Исключение возникает когда WPF элемент ловит INCC из другого потока. Если привязки в View к коллекции нет, то заполняется из другого потока без проблем. Если из несколькими потоков, то может произойти наложение элементов, то есть фактически какие-то элементы могут пропасть. Но исключений не будет. Вроде, из разных. Но у вас же нет привязки коллекции к WPF-элементу. Поэтому исключения не возникаю. Вероятность наложения элементов тоже мизерна. Создаётся всего 10 элементов. Пока запустится второй поток - первый уже отработает.
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
|
25.09.2019, 13:24 [ТС] | 10 |
Там снять комментарий с задержки можно, я пробовал, всё Ок.
Хорошо, собственно вопрос в том, что делать если я всё таки захочу сделать эту привязку! Чем заменить ObservableCollection<T> или её можно как-то адаптировать под наполнение с разных потоков?
0
|
Модератор
![]() |
|
25.09.2019, 13:33 | 11 |
Задержка роли не играет.
Создание и запуск нового потока - это миллисекунды. А заполнение коллекции пятью элементами - сотые или тысячные доли миллисекунды. Добавлено через 6 минут Я уже написал выше. Напрямую прокидывать INCC из Model в WPА View нельзя. Заменить её не чем. По крайней мере из дефолтных. В принципе, сторона ViewModel обращённая к View должна работать только в основном потоке. Сторона обращённая к Model работает в потоках Модели. А внутри себя VM приводит все изменения из разных потоков к основному потоку.
0
|
Модератор
![]() |
|
25.09.2019, 13:37 | 12 |
Адаптировать можно. Создать наследника и перенаправлять события INCC в основной поток.
Но такая реализация не думаю что будет правильной. Этот механизм должен быть снаружи коллекции, так как изменение потоков это не функционал коллекции, а функционал ViewModel.
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
|
25.09.2019, 13:46 [ТС] | 13 |
Да, подключил ObservableCollection<T> к View и всё сразу рухнуло. (см. рис 1).
Мля это полный П... ![]() Это придётся перелопачивать весь код из-за того что я не могу вывести на экран табличку! ЭТО ПОДСТАВА! ![]() Чего делать ребята? ![]()
0
|
1498 / 892 / 325
Регистрация: 17.05.2015
Сообщений: 3,386
|
|
25.09.2019, 13:50 | 14 |
Чипс, задачу свою опишите, что делают потоки и как заполняется коллекция
Добавлено через 1 минуту ну дык вы же его писали без оглядки на последствия => ваш код тут не подходит => надо лопатить
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
|
25.09.2019, 13:54 [ТС] | 15 |
Код выложен выше Сегодня, 12:16 [ТС]
Задача: -наполнить ObservableCollection<T> -вывести на экран во View Если надо, могу выложить код интефейса. Добавлено через 1 минуту Я думал, что можно будет взять другую коллекцию и вывести её на экран ![]() Добавлено через 44 секунды Откуда мне было знать, что есть только ObservableCollection<T> для вывода на экран коллекций! Добавлено через 1 минуту Я не могу, его уже слишком много! Надо какой нибудь костыль!
0
|
Модератор
![]() |
||||||
25.09.2019, 13:55 | 16 | |||||
Для вашего примера MainWindowVM
0
|
1498 / 892 / 325
Регистрация: 17.05.2015
Сообщений: 3,386
|
|
25.09.2019, 13:55 | 17 |
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
|
25.09.2019, 13:59 [ТС] | 18 |
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
||||||||||||||||
25.09.2019, 14:09 [ТС] | 19 | |||||||||||||||
Есть код, который должен:
-по нажатию кнопки "Start" наполнить ObservableCollection<T> из разных потоков -вывести на экран во View Проблема в том, что ObservableCollection<T> нельзя наполнять из разных потоков, если она привязана к View. При попытки это сделать возникает следующая ошибка (см. рис 3) Что делать? View
MainWindowVM
Number
0
|
82 / 60 / 17
Регистрация: 21.08.2015
Сообщений: 1,046
|
|
25.09.2019, 14:21 [ТС] | 20 |
Необходимо наполнить выводимую на экран коллекцию из разных потоков.
Не знаю, как понятней объяснить =( Задайте наводящие вопросы или скажите, чего вы не поняли?
0
|
25.09.2019, 14:21 | |
Помогаю со студенческими работами здесь
20
Заполнение коллекции из БД Заполнение коллекции Коллекции разных типов Заполнение ListView из коллекции Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |