Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/35: Рейтинг темы: голосов - 35, средняя оценка - 4.60
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203

Dispatcher и многопоточность WPF

11.08.2020, 11:46. Показов 8252. Ответов 44

Студворк — интернет-сервис помощи студентам
Всем привет, помоги пожалуйста разобраться
Изучаю многопоточность C#, в консоле все работает как надо но вот в WPF ругается
выкидывает исключение
Данный тип CollectionView не поддерживает изменения в своем SourceCollection из потока, отличного от потока Dispatcher.
Сам процесс загрузки и добавления происходить в отдельной библиотеке.

во ViewModel получает данные
C#
1
AccountsList = account.GetListAccounts();
аналогично и с добавлением account в данном случае это переменная хранилища в библиотеке

C#
1
account.AddItems(item);

непосредственно сам способ добавления
C#
1
2
3
private ObservableCollection<Accounts> ListAccount = new ObservableCollection<Accounts>();
 
ListAccount.Add(accounts);
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.08.2020, 11:46
Ответы с готовыми решениями:

Многопоточность в WPF
Здравствуйте, нужна ваша помощь. Пишу приложение, позволяющее передавать файлы по сети, суть примерно такая: к серверу, содержащему...

Многопоточность в WPF
Доброго времени суток. При реализации того, чтобы объект &quot;Image&quot; из xaml брал ImageSource из списка BitmapSource с некоторой задержкой (в...

Остановить Dispatcher
Всем привет, не могу остановить поток Dispatcher'а Dispatcher.BeginInvoke(new ThreadStart(delegate { shower();})); public void...

44
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 19:20  [ТС]
Студворк — интернет-сервис помощи студентам
Элд Хасп,
Не виснет, в примере всего 32 записи. Пока что! начал делать реализацию с разных файлов и буду создавать записи

Добавлено через 9 минут
Элд Хасп,

Событие можно посылать даже не по концу загрузки файла, а допустим через 100 загруженных записей.
Но десериализация будет грузить файл сразу весь, поэтому этот вариант актуален только для БД или WEB.
Сейчас я получается каждую запись обновляю в событии, но обновлять каждые сто это хороший вариант, спасибо!

Он у меня загружает весь фаил, затем перебирает.

Добавлено через 3 минуты
Элд Хасп,
Вариант до этого мне нравился тем что все записи динамически одновлялись, ведь в этом смысл ObservableCollection

Но сейчас приходится каждую запись обновлять весь список, это ресурсо затраты
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,181
Записей в блоге: 2
12.08.2020, 20:40
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Но сейчас приходится каждую запись обновлять весь список, это ресурсо затраты
Нет не должно быть так.
В ViewModel у вас список в типе ObservableCollection.
ViewModel получает данные из Модели (Repository), преобразует их в нужный тип, переходит в Диспетчер и там уже сформированные элементы добавляет в ObservableCollection.

То есть вся работа происходит не в потоке Диспетчера, асинхронно.
В Диспетчере только изменяется ObservableCollection.

Добавлено через 1 минуту
Если изменений много.
То чтобы не вис GUI надо разбить партию элементов по сотне.
И на каждую сотню создать в Диспетчере свою задачу.
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
13.08.2020, 15:12  [ТС]
Элд Хасп,

Нашел причину почему зависало все пока не загрузит...

В этом примере я ставил
C#
1
Application.Current.Dispatcher?.Invoke((
перед выполнением цыкла

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Application.Current.Dispatcher?.Invoke(() =>{
                    int count = 0;
                    foreach (var item in GetAccounts)
                    {
                        Thread.Sleep(500);
                        switch (item.TypeId)
                        {
                            case 2: ListAccount.Add(new AccountPersonal(item)); break;
                            case 3: ListAccount.Add(new AccountDeposit(item)); break;
                            case 4: ListAccount.Add(new AccountCredits(item)); break;
                        }
                        count++;
                        ProgressBar progress = new ProgressBar
                        {
                            ProgressCount = GetAccounts.Count,
                            ProgressName = "Загрузка",
                            ProgressValue = count
                        };
                        progress.GetValue(progress);
                    }
                });

Здесь я сделал по другому
C#
1
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
вставил внутрь цыкла, на каждую итерацию, и все заработало как я и хотел)))

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int count = 0;
                    foreach (var item in GetAccounts)
                    {
                        Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
                         (Action)delegate ()
                         {
                            switch (item.TypeId)
                            {
                               case 2: ListAccount.Add(new AccountPersonal(item)); break;
                               case 3: ListAccount.Add(new AccountDeposit(item)); break;
                               case 4: ListAccount.Add(new AccountCredits(item)); break;
                            }
 
                             count++;
 
                             ProgressBar.GetValue("Загрузка", GetAccounts.Count, count);
                         });
                    }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,181
Записей в блоге: 2
13.08.2020, 18:32
Лучший ответ Сообщение было отмечено nikolaynn1984 как решение

Решение

Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
вставил внутрь цыкла, на каждую итерацию, и все заработало как я и хотел)))
Лучше сначала получить коллекцию Account, а потом по ней обновить ListAccount
Для большого количества элементов это будет выглядеть примерно так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
List<Accounts> list = null;
for(int count = 0; count <GetAccounts.Count; count++)
{
     if (list == null) 
         list = new List<Accounts>(100);
     switch (GetAccounts[count].TypeId)
     {
        case 2: ListAccount.Add(new AccountPersonal(GetAccounts[count])); break;
        case 3: ListAccount.Add(new AccountDeposit(GetAccounts[count])); break;
        case 4: ListAccount.Add(new AccountCredits(GetAccounts[count])); break;
      }
 
      if (count % 100 == 0 || count == GetAccounts.Count -1
      {
             Application.Current.Dispatcher.BeginInvoke(()=>
             {
                 list.ForEach(acc => ListAccount.Add(acc));
                 ProgressBar.GetValue("Загрузка", GetAccounts.Count, count);
             });
            list == null;
       }
}
1
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
13.08.2020, 18:48  [ТС]
Элд Хасп,

Хорошо, спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.08.2020, 18:48

Dispatcher.BeginInvoke и Sleep
Подскажите почему при такой конструкции может не работать как надо блокировка кнопок? Когда не было sleep все работало как надо. Может надо...

mvc-dispatcher-servlet.xml
При создании в идеи приложения SpringMVC создается файл &quot;mvc-dispatcher-servlet.xml&quot;, но он очень похож на spring-config.xml - найстройку...

В чем отличие SynchronizationContext и Dispatcher
Всем доброго времени суток. Заметил что на форуме в ответах многие используют класс SynchronizationContext. Я в своем коде всегда...

Вызов Dispatcher.Invoke из двух методов
Приложение должно по нажатию кнопки скрывать окно, через некоторое время открывать его, но кнопка должна быть невидима. Ещё через некоторое...

Dispatcher.Invoke() не вызывает указанный делегат
Метод MethodForThread() работает в другом потоке и по окончании он должен вызвать обратный метод AsyncCallbackMethod() в потоке, в котором...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
45
Ответ Создать тему
Новые блоги и статьи
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
Генератор паролей (вариант №2)
Maks 30.10.2026
Обновленная версия ранее созданной обработки. Добавлены следующие реквизиты типа Булево: - Буквы; - Цифры; - Символы. Изменена логика команды "Сгенерировать" и процедуры "ПриОткрытии":. . .
Генератор паролей (вариант №1)
Maks 29.10.2026
Реализация из решения ниже выполнена исключительно по моей инициативе, дабы облегчить себе работу в создании паролей для администрируемых мною сервисов и пользователей. Самым главным критерием для. . .
Установка ChatGPT (Codex) на Windows без использования Microsoft Store
Fabien159 28.10.2026
Здравствуйте всем читающим! Опишу процесс установки ChatGPT (Codex) на Windows, если по каким-то причинам у вас не получается устанавить его через Microsoft Store. И так: 1. Скачиваем с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru