Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
0 / 0 / 2
Регистрация: 01.10.2012
Сообщений: 18
.NET 4.x

WPF async void fun() для событий контролла. (MapCOntrol.WPF)

18.11.2016, 04:12. Показов 3387. Ответов 4

Author24 — интернет-сервис помощи студентам
Задача: Отмечаем чекбокс элементы и рисуем их на карте.

При нажатии на кнопку выполняется событие, где вызывается функция, в которой запускается цикл

C# Скопировано
1
2
3
4
5
6
7
8
9
10
11
public void DrawObjectTree()//функция
{
 foreach (var tb_head in itemPlHead.Children)//цикл
 {
  if (tb_head is Controls.CheckBox)
  {
        CheckBox cb = (CheckBox)tb_head;
         cb.IsChecked = true;//ставим галочки для списка чекбоксов
  }
 }
}
При отметке на чекбоксе возникает событие
C# Скопировано
1
2
3
4
5
6
7
8
async private void CheckBox_Checked(object sender, EventArgs e)
{
paths.Add(new Path()){...};
...
var t = await GetCoordAsync(_var, context, CancellationToken.None);
MapPanel.SetLocation(paths[paths.Count - 1],new Location() { Latitude = t.lat, Longitude = t.lon });
map.Children.Add(paths[paths.Count - 1]);//ошибка тут
}
Т.е. асинхронно находим координаты и рисуем paths на карте (MapControl.WPF). Как находятся координаты, схематично

C# Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
async Task<Coord> GetCoordAsync(var _var, context db, CancellationToken ct)
{
 return await Task.Run(() =>
 {
  try
  {
    Coord result = db.GetCoord(_var);
    ct.ThrowIfCancellationRequested();
    return result ;
   }
 catch ...
 }, ct);
}
Если координату находить синхронно, то все корректно работает (кроме UI). В таком виде ошибка Указанный элемент Visual уже является дочерним по отношению к другому элементу Visual или корневому элементу CompositionTarget.

Насколько я понял причину, то это из-за того, что функция собития для чек-бокса у нас async и void, то есть внутри функции CheckBox_Checked как только попадается await тут же возвращается выполнение родительскому потоку. И начинается выполнятся функция для второго "рисунка".

C# Скопировано
1
map.Children.Add(paths[paths.Count - 1]);//ошибка тут, paths[] одинаково для первого "рисунка" и для второго. (Один отрисовывается нормально, после второго крашитmся). В синхронном варианте, для первого рисунка paths.Count=1 , для 2-го paths.Count=2 и т.д. В асинхронном у всех 1 - из-за этогО и ошибка вылетает
Как бы это исправить..
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.11.2016, 04:12
Ответы с готовыми решениями:

[WPF] Добавить обработчик событий для динамического элемента
На Canvas динамически создаются элементы (Label) Этим элементам нужно присвоить обработчик событий. Я делаю так: public void...

[WPF] ComboBox async SelectedIndex не работает
У меня ComboBox заполняется (с использованием async/await) из базы данных при этом не работает тег SelectedIndex в XAML, если же...

Async/await в WPF - зависает приложение
Всем привет! Возникла проблема, бьюсь над ней уже второй день. Прочитал море статей по асинхронному программированию. Суть: мне надо...

4
1150 / 858 / 263
Регистрация: 30.04.2009
Сообщений: 3,599
20.11.2016, 01:04
Лучший ответ Сообщение было отмечено Artur919191 как решение

Решение

Пока выполняется GetCoordAsync в paths могут быть добавлены новые элементы.
Ошибка в том, что после GetCoordAsync берется последний элемент из списка paths.
Нужно запоминать добавленный элемент и использовать его:

C# Скопировано
1
2
3
4
5
6
7
8
9
async private void CheckBox_Checked(object sender, EventArgs e)
{
var newPath = new Path();
paths.Add(newPath){...};
...
var t = await GetCoordAsync(_var, context, CancellationToken.None);
MapPanel.SetLocation(newPath ,new Location() { Latitude = t.lat, Longitude = t.lon });
map.Children.Add(newPath);
}
1
Эксперт .NET
 Аватар для kolorotur
17810 / 12961 / 3381
Регистрация: 17.09.2011
Сообщений: 21,250
20.11.2016, 11:43
Цитата Сообщение от Artur919191 Посмотреть сообщение
C# Скопировано
1
2
3
async Task<Coord> GetCoordAsync(var _var, context db, CancellationToken ct)
{
 return await Task.Run(() =>
Не по теме: если в асинхронном методе отсутствует await между инструкциями, то лучше просто возвращать созданную задачу:
C# Скопировано
1
2
3
Task<Coord> GetCoordAsync(var _var, context db, CancellationToken ct)
{
 return Task.Run(() =>
1
0 / 0 / 2
Регистрация: 01.10.2012
Сообщений: 18
21.11.2016, 10:37  [ТС]
Ну ошибка да, я понимал в чем, а вот как решить не догадался..

Спасибо!

Добавлено через 8 минут
Интересно...а можно узнать почему? (Два await делают , что-то вроде конвертации из task<T> в T? Поэтому?)

А вызов функции не поменяется, да?
C# Скопировано
1
2
var t = await GetCoordAsync(_var, context, ...);
MapPanel.SetLocation(...,new Location() { Latitude = t.lat, Longitude = t.lon });
0
Эксперт .NET
 Аватар для kolorotur
17810 / 12961 / 3381
Регистрация: 17.09.2011
Сообщений: 21,250
21.11.2016, 11:10
Цитата Сообщение от Artur919191 Посмотреть сообщение
а можно узнать почему?
На каждый await создается конечный автомат, который мониторит статус задачи и вызывает продолжение метода по ее окончании.
Кроме того, при использовании await все локальные переменные метода переезжают в кучу, что добавляет нагрузку на сборщика.
Если метод не разбивается на части через await, то прямым возвратом задачи вы срезаете лишнее создание и работу автомата, что немного улучшает производительность.

Цитата Сообщение от Artur919191 Посмотреть сообщение
А вызов функции не поменяется, да?
Да, снаружи всё остается как было и работает точно так же.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.11.2016, 11:10
Помогаю со студенческими работами здесь

ColorDialog для WPF. Копии всякого старья для WPF
Последние три дня мучился в поисках ColorDialog для WPF. Не стороннего заменителя, а максимально похожего контрола. Потом просто взял, да и...

Проблемы с конструкцией async\await при использовании WPF или Windows Forms
Добрый день! Написал библиотечку, использующую, в том числе конструкции async-await. Всё работает, при компиляции в виде консольного...

WPF команды и MVVM. Часть 2. Всплытие команд. Реализация команды для списка элементов [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html На практике часто встречаются случаи когда команда и кнопка...

Обработка событий WPF
re.MouseDown += new MouseButtonEventHandler(re_MouseDown); re.MouseDown += re_MouseDown; Есть ли разница между этими записями?...

Обработка событий в textbox wpf
Вечер добрый. Работаю с wpf, не могу правильно создать событие, связанное с щелчком мыши по textbox, перепробовала все варианты (preview,...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Анализ и линтинг кода JavaScript: ESLint, Prettier и JSHint
run.dev 26.04.2025
JavaScript прошёл долгий путь от простого языка для анимации веб-страниц до основы современной веб-разработки. С ростом сложности приложений, увеличением кодовых баз и масштабированием команд. . .
Паттерны в Python: Singleton, Factory и Observer
py-thonny 26.04.2025
Паттерны проектирования — это проверенные временем решения типовых проблем разработки программного обеспечения. Их история берёт начало с книги "Приёмы объектно-ориентированного проектирования. . . .
Исключения в C#: Stack Overflow, Access Violation и Out of memory
stackOverflow 26.04.2025
Исключения в C# — это не только механизм оповещения о проблемах, а целое искусство управления потоком выполнения программы в экстремальных ситуациях. Обычное исключение, например,. . .
Логирование в C# ASP.NET Core с помощью Serilog, ElasticSearch, Kibana
stackOverflow 25.04.2025
Помните те времена, когда для анализа проблемы приходилось подключаться к серверу, искать нужный лог-файл среди десятков других и вручную фильтровать тысячи строк в поисках ошибки? К счастью, эти дни. . .
Структура "железный OnKeyUp" вместо антидребезга. Полностью асинхронный счётчик.
Hrethgir 25.04.2025
Программа для симуляции схемы - Logisim Evolution В общем какое-то время отвлёкся, так было надо, теперь когда запилю это на verilog и FPGA , досоставлю заявку в ФИПС на полезную модель - не готов. . .
Автоматизация Amazon Web Services (AWS) с Boto3 в Python
py-thonny 25.04.2025
Облачные вычисления стали неотъемлемой частью современной ИТ-инфраструктуры, а Amazon Web Services (AWS) занимает лидирующие позиции среди провайдеров облачных услуг. Управление многочисленными. . .
Apache Kafka vs RabbitMQ в микросервисной архитектуре
ArchitectMsa 25.04.2025
Современная разработка ПО всё чаще склоняется к микросервисной архитектуре — подходу, при котором приложение разбивается на множество небольших, автономных сервисов. В этой распределённой среде. . .
Параллельное программирование с OpenMP в C++
NullReferenced 24.04.2025
Параллельное программирование — подход к созданию программ, когда одна задача разбивается на несколько подзадач, которые могут выполняться одновременно. Оно стало необходимым навыком для. . .
Цепочки методов в C# с Fluent API
UnmanagedCoder 24.04.2025
Современное программирование — это не только решение функциональных задач, но и создание кода, который удобно поддерживать, расширять и читать. Цепочки методов и Fluent-синтаксис в C# стали мощным. . .
Мульти-тенантные БД с PostgreSQL Row Security
Codd 23.04.2025
Современные облачные сервисы и бизнес-приложения всё чаще обслуживают множество клиентов в рамках единой программной инфраструктуры. Эта архитектурная модель, известная как мульти-тенантность, стала. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер