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

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

11.08.2020, 11:46. Показов 8206. Ответов 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
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 16:31
Студворк — интернет-сервис помощи студентам
Давайте начнём с самих "низов".
С первичными данными работает класс Repository.
Как я понял, именно он считывает файлы.

Если так, то "с какого перепуга" его методы возвращают ObservableCollection?
Этот тип предназначен для Представления, а чего он здесь делает?

Почему при каждом обращении к методу происходит новое считывание ВСЕХ данных?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        private void LoadData()
        {
            this.physicalClients = SerializeData.GetItems(physicalClients, Path.PhysicalClient);
            this.busines = SerializeData.GetItems(busines, Path.Business);
            this.statuses = SerializeData.GetItems(statuses, Path.Statuses);
            this.customers = SerializeData.GetItems(customers, Path.Customers);
        }
        /// <summary>Получение данных клиентов</summary>
        /// <returns>Список клиентов</returns>
        public ObservableCollection<Customers> GetCustomers() { LoadData(); return this.customers; }
        /// <summary>Получение списка данных физ.лих - клиентах</summary>
        /// <returns>Списко физюлих</returns>
        public ObservableCollection<PhysicalClient> GetPhysicalClients() { LoadData(); return physicalClients; }
        /// <summary>Получение списка данных юр.лиц - клиентов</summary>
        /// <returns>Список юр.лих</returns>
        public ObservableCollection<Busines> GetBusines() { LoadData(); return busines; }
Добавлено через 55 секунд
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Вся сложность в том что окно зависает то тех пор пока не отработает второй поток!
В какой строке в каом файле он создаётся?
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 16:59  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Почему при каждом обращении к методу происходит новое считывание ВСЕХ данных?
Это я сейчас исправляю...это не правильно!

Цитата Сообщение от Элд Хасп Посмотреть сообщение
В какой строке в каом файле он создаётся?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 /// <summary>
    /// Логика взаимодействия для App.xaml
    /// </summary>
    public partial class App : Application
    {
 
        private delegate void Factorial();
        private void App_StartupAsync(object sender, StartupEventArgs e)
        {
 
            AccountViewModel viewModel = new AccountViewModel();
            MainWindow = new AccountView() { DataContext = viewModel };
            MainWindow.Show();
           
             RepositoryAccount.LoadAsync();   [B]//Здесь начинает грузить данные[/B]
        }
 
        private static AccountData.Repository repositoryAccount = new AccountData.Repository();
        public static AccountData.Repository RepositoryAccount
        {
            get {  return repositoryAccount;  }
            set { repositoryAccount = value; }
        }
 
        private static CustomersData.Repository repositoryCustom = new CustomersData.Repository();
        public static CustomersData.Repository RepositoryCustom
        {
            get { return repositoryCustom; }
            set { repositoryCustom = value; }
        }
    }
далее - здесь загружает

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 public Repository()
        {
            this.GetPersonals = new ObservableCollection<Personal>();
            this.GetDeposits = new ObservableCollection<Deposit>();
            this.GetCredits = new ObservableCollection<Credits>();
            GetAccounts = new ObservableCollection<Accounts>();
            GetPersonals = SerializeData.GetItems(GetPersonals, Path.Personal);
            GetDeposits = SerializeData.GetItems(GetDeposits, Path.Deposit);
            GetCredits = SerializeData.GetItems(GetCredits, Path.Credit);
            GetAccounts = SerializeData.GetItems(GetAccounts, Path.BankAccount);
            ListAccount = new ObservableCollection<Accounts>();
        }
       
 
        public ObservableCollection<Accounts> GetNotFromId(int id)
        {
            var items = ListAccount.Where(s => s.Id != id).Where(t => t.TypeId == 2);
            return new ObservableCollection<Accounts>(items);
        }
        public Task LoadAsync() => Task.Run(LoadAccounts);   //Непосредственно запуск загрузки в отдельном потоке
 
        /// <summary>
        /// Загрузка списка всех Счетов
        /// </summary>
        public static void LoadAccounts()   
        {
            try
            {
                //Thread.Sleep(100);
                Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    int count = 0;
                    foreach (var item in GetAccounts)
                    {
                        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);
                    }
                });
 
            }
            catch(Exception e)
            {
                
                MessageBox.Show(e.Message);
 
            }
           
        }
        /// <summary>
        /// Загрузка списк счетов
        /// </summary>
        /// <returns></returns>
        public ObservableCollection<Accounts> GetListAccounts()  {  return ListAccount; }
Добавлено через 21 минуту
Элд Хасп,
Короткое кино
https://cloud.mail.ru/public/dziU/4Ly3LLgLG
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 17:13
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Короткое кино
Очень мутно.

Если можете то лучше вставляйте ролики с YuoTube.

Пример тегов [YOUTUBE]WEzqCW_lmIs[/YOUTUBE]



Добавлено через 3 минуты
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
далее - здесь загружает
Диспетчер - это ОДИН поток на всё приложение и строка Application.Current.Dispatcher.InvokeAsync(() => будет блокировать этот поток на время своего выполнения.
Все данные надо обрабатывать в других потоках.
А в Диспетчере вы делаете только быструю обработку привязанной коллекции ObservableCollection.

Добавлено через 1 минуту
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Непосредственно запуск загрузки в отдельном потоке
Вот в этой строке public Task LoadAsync() => Task.Run(LoadAccounts); вы создаёте задачу в другом потоке.
Но в задаче выполняется метод, в котором выполнение перебрасывается опять в Диспетчер.
Толку от такой асинхронности - ноль.

Добавлено через 1 минуту
Сколько предположительно элементов в коллекции ListAccount будет по завершении загрузки?
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 17:14  [ТС]
Элд Хасп,


Элд Хасп, В настройках нужно просто качество поменять, в ютуб еще не выбрасывал видео просто)
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 17:19  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Вот в этой строке public Task LoadAsync() => Task.Run(LoadAccounts); вы создаёте задачу в другом потоке.
Но в задаче выполняется метод, в котором выполнение перебрасывается опять в Диспетчер.
Толку от такой асинхронности - ноль.
Все верно, но если я загружаю без диспетчера, то мы благополучно возвращаемся в начало темы, и получаем исключение
Миниатюры
Dispatcher и многопоточность WPF  
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 17:19
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
В настройках нужно просто качество поменять
Поменял на 1080 - стало нормально.
Но звука почти не слышно.
Сделал на максимум - еле слышно, ну уровне шумов.
Не разобрать что говорите.
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 17:20  [ТС]
Элд Хасп, Со звуком посложнее, тому виной не облако, мой микрофон(((
Но в целом там понятно что и где?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 17:23
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Все верно, но если я загружаю без диспетчера, то мы благополучно возвращаемся в начало темы, и получаем исключение
А я уже написал!
Цитата Сообщение от Элд Хасп Посмотреть сообщение
С первичными данными работает класс Repository.
Как я понял, именно он считывает файлы.
Если так, то "с какого перепуга" его методы возвращают ObservableCollection?
Этот тип предназначен для Представления, а чего он здесь делает?
Не должно быть в Repository (а это часть Модели) не типа ObservableCollection, ни тем более обращения в Диспетчеру.
Этот тип, при нормальной структуре Решения, должен находится в проекте у которого даже ссылки нет на Application и Диспетчер.

Добавлено через 1 минуту
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Но в целом там понятно что и где?
Более менее проясняется.
Но сразу пишу - большие ошибки в проектировании архитектуры приложения.
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 17:24  [ТС]
Элд Хасп, То есть все должно быть в List<> и только ViewModel передавать ObservableCollection?

Добавлено через 23 секунды
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но сразу пишу - большие ошибки в проектировании архитектуры приложения.
Я только учусь)))
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 17:34
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Я только учусь)))
Поэтому и говорю, давайте начнём с низов.
А то переделывать "верха" когда неправильно работает их основание неэффективно.

И вы не ответили, какого размера должна быть коллекция ObservableCollection передаваемая в представление?
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 17:36  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
И вы не ответили, какого размера должна быть коллекция ObservableCollection передаваемая в представление?
Примерно 20 мегабайт
Я сейчас все переделываю...
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 17:40
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
По размерам точно не могу пока сказать....
Ну, примерно сколько в ней может быть элементов.
Очень большое количество может "повесть" WPF GUI.
На каждый элемент, будет создаваться своя коллекция UI элементов.
Это может оказаться очень накладно.

Я не помню как у DataGrid настроена виртуализация.

Добавлено через 39 секунд
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Я сейчас все переделываю...
Давайте лучше согласуем, что и как переделывать.
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 17:43  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Давайте лучше согласуем, что и как переделывать.
Мне идея с ObservableCollection с самого начала не нравилась, сейчас переделаю все в LIst

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ну, примерно сколько в ней может быть элементов.
Общее количество записей будет 10 миллионов,

каждый миллион я буду сохранять в отдельном файле, и в пуле загружать
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 17:47
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
сейчас переделаю все в LIst
Там даже не лист должен быть, а IEnumerable или (лучше) ReadOnlyCollection

Добавлено через 51 секунду
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Общее количество записей будет 10 миллионов,
И их всех вы хотите передать в Представление...
Это плохая идея.

Добавлено через 40 секунд
Если дождаться загрузки, GUI при промотке не лагает?
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 17:59  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
И их всех вы хотите передать в Представление...
Это плохая идея.
Такая задача)
Мне нужно добиться того чтоб хотя бы эти данные грузились как положено, дальше я создаю такое количество записей и тестирую)

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если дождаться загрузки, GUI при промотке не лагает?
Еще не загружал такой объем, но каким то образом это нужно обрабатывать, на сколько я знаю что DataGrid не должен лагать при таких объемах.

Добавлено через 2 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
ReadOnlyCollection
Если будет ReadOnlyCollection, как он будет обновлять данные в этих коллекциях?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 18:07
Если дождаться загрузки, GUI при промотке не лагает?
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Еще не загружал такой объем, но каким то образом это нужно обрабатывать, на сколько я знаю что DataGrid не должен лагать при таких объемах.
Надо проверить.
Если будет лагать, придётся настраивать виртуализацию.
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 18:09  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Надо проверить.
Если будет лагать, придётся настраивать виртуализацию.
То есть частями загружать и показывать?

Я правильно понимаю?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 18:14
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
Если будет ReadOnlyCollection, как он будет обновлять данные в этих коллекциях?
Он не должен ничего обновлять!

У вас же проблема из-за загрузки с файлов.

Загрузили файл.
Создали событие, что загрузка завершена.
ViewModel поймала событие.
Из события считала данные - коллекцию ReadOnlyCollection.
Преобразовала эти данные в нужный тип.
Потом перешла в Диспетчер и обновила коллекцию уже созданными типами.

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

Добавлено через 2 минуты
Цитата Сообщение от nikolaynn1984 Посмотреть сообщение
То есть частями загружать и показывать?
Я правильно понимаю?
Да.
Но я ещё раз пишу - надо проверить.
У ListBox я точно знаю, виртуализация настроена по дефолту.
Там создаются только видимые элементы.

А вот у DataGrid - не помню.
Дождитесь конца загрузки и проверьте.
0
279 / 10 / 0
Регистрация: 27.04.2016
Сообщений: 203
12.08.2020, 18:58  [ТС]
Элд Хасп, Элд Хасп,

По исправлял всё и вот!)

https://cloud.mail.ru/public/dziU/4Ly3LLgLG
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.08.2020, 19:04
Виснет на 32-ом?
GUI стоит или просто загрузка не продолжается?

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

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() в потоке, в котором...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru